diff options
Diffstat (limited to 'lib/rubygems/source')
| -rw-r--r-- | lib/rubygems/source/git.rb | 110 | ||||
| -rw-r--r-- | lib/rubygems/source/installed.rb | 18 | ||||
| -rw-r--r-- | lib/rubygems/source/local.rb | 76 | ||||
| -rw-r--r-- | lib/rubygems/source/lock.rb | 21 | ||||
| -rw-r--r-- | lib/rubygems/source/specific_file.rb | 26 | ||||
| -rw-r--r-- | lib/rubygems/source/vendor.rb | 11 |
6 files changed, 144 insertions, 118 deletions
diff --git a/lib/rubygems/source/git.rb b/lib/rubygems/source/git.rb index 2e3fa03730..baf2f9dd4c 100644 --- a/lib/rubygems/source/git.rb +++ b/lib/rubygems/source/git.rb @@ -1,5 +1,4 @@ -require 'digest' -require 'rubygems/util' +# frozen_string_literal: true ## # A git gem for use in a gem dependencies file. @@ -12,7 +11,6 @@ require 'rubygems/util' # source.specs class Gem::Source::Git < Gem::Source - ## # The name of the gem created by this git gem. @@ -50,41 +48,42 @@ class Gem::Source::Git < Gem::Source # repository may contain multiple gems. If +submodules+ is true, submodules # will be checked out when the gem is installed. - def initialize name, repository, reference, submodules = false - super(nil) - + def initialize(name, repository, reference, submodules = false) + require_relative "../uri" + @uri = Gem::Uri.parse(repository) @name = name @repository = repository - @reference = reference + @reference = reference || "HEAD" @need_submodules = submodules @remote = true @root_dir = Gem.dir - @git = ENV['git'] || 'git' end - def <=> other + def <=>(other) case other when Gem::Source::Git then 0 - when Gem::Source::Installed, + when Gem::Source::Vendor, Gem::Source::Lock then -1 when Gem::Source then 1 - else - nil end end - def == other # :nodoc: - super and - @name == other.name and - @repository == other.repository and - @reference == other.reference and + def ==(other) # :nodoc: + super && + @name == other.name && + @repository == other.repository && + @reference == other.reference && @need_submodules == other.need_submodules end + def git_command + ENV.fetch("git", "git") + end + ## # Checks out the files for the repository into the install_dir. @@ -93,19 +92,22 @@ class Gem::Source::Git < Gem::Source return false unless File.exist? repo_cache_dir - unless File.exist? install_dir then - system @git, 'clone', '--quiet', '--no-checkout', + unless File.exist? install_dir + system git_command, "clone", "--quiet", "--no-checkout", repo_cache_dir, install_dir end Dir.chdir install_dir do - system @git, 'fetch', '--quiet', '--force', '--tags', install_dir + system git_command, "fetch", "--quiet", "--force", "--tags", install_dir + + success = system git_command, "reset", "--quiet", "--hard", rev_parse - success = system @git, 'reset', '--quiet', '--hard', @reference + if @need_submodules + require "open3" + _, status = Open3.capture2e(git_command, "submodule", "update", "--quiet", "--init", "--recursive") - success &&= - Gem::Util.silent_system @git, 'submodule', 'update', - '--quiet', '--init', '--recursive' if @need_submodules + success &&= status.success? + end success end @@ -117,13 +119,13 @@ class Gem::Source::Git < Gem::Source def cache # :nodoc: return unless @remote - if File.exist? repo_cache_dir then + if File.exist? repo_cache_dir Dir.chdir repo_cache_dir do - system @git, 'fetch', '--quiet', '--force', '--tags', - @repository, 'refs/heads/*:refs/heads/*' + system git_command, "fetch", "--quiet", "--force", "--tags", + @repository, "refs/heads/*:refs/heads/*" end else - system @git, 'clone', '--quiet', '--bare', '--no-hardlinks', + system git_command, "clone", "--quiet", "--bare", "--no-hardlinks", @repository, repo_cache_dir end end @@ -132,7 +134,7 @@ class Gem::Source::Git < Gem::Source # Directory where git gems get unpacked and so-forth. def base_dir # :nodoc: - File.join @root_dir, 'bundler' + File.join @root_dir, "bundler" end ## @@ -145,7 +147,7 @@ class Gem::Source::Git < Gem::Source ## # Nothing to download for git gems - def download full_spec, path # :nodoc: + def download(full_spec, path) # :nodoc: end ## @@ -154,16 +156,18 @@ class Gem::Source::Git < Gem::Source def install_dir # :nodoc: return unless File.exist? repo_cache_dir - File.join base_dir, 'gems', "#{@name}-#{dir_shortref}" + File.join base_dir, "gems", "#{@name}-#{dir_shortref}" end - def pretty_print q # :nodoc: - q.group 2, '[Git: ', ']' do - q.breakable - q.text @repository + def pretty_print(q) # :nodoc: + q.object_group(self) do + q.group 2, "[Git: ", "]" do + q.breakable + q.text @repository - q.breakable - q.text @reference + q.breakable + q.text @reference + end end end @@ -171,16 +175,24 @@ class Gem::Source::Git < Gem::Source # The directory where the git gem's repository will be cached. def repo_cache_dir # :nodoc: - File.join @root_dir, 'cache', 'bundler', 'git', "#{@name}-#{uri_hash}" + File.join @root_dir, "cache", "bundler", "git", "#{@name}-#{uri_hash}" end ## # Converts the git reference for the repository into a commit hash. def rev_parse # :nodoc: + hash = nil + Dir.chdir repo_cache_dir do - Gem::Util.popen(@git, 'rev-parse', @reference).strip + hash = Gem::Util.popen(git_command, "rev-parse", @reference).strip end + + raise Gem::Exception, + "unable to find reference #{@reference} in #{@repository}" unless + $?.success? + + hash end ## @@ -192,41 +204,41 @@ class Gem::Source::Git < Gem::Source return [] unless install_dir Dir.chdir install_dir do - Dir['{,*,*/*}.gemspec'].map do |spec_file| + Dir["{,*,*/*}.gemspec"].filter_map do |spec_file| directory = File.dirname spec_file file = File.basename spec_file Dir.chdir directory do spec = Gem::Specification.load file - if spec then + if spec spec.base_dir = base_dir spec.extension_dir = - File.join base_dir, 'extensions', Gem::Platform.local.to_s, + File.join base_dir, "extensions", Gem::Platform.local.to_s, Gem.extension_api_version, "#{name}-#{dir_shortref}" spec.full_gem_path = File.dirname spec.loaded_from if spec end spec end - end.compact + end end end ## - # A hash for the git gem based on the git repository URI. + # A hash for the git gem based on the git repository Gem::URI. def uri_hash # :nodoc: + require_relative "../openssl" + normalized = - if @repository =~ %r%^\w+://(\w+@)?% then - uri = URI(@repository).normalize.to_s.sub %r%/$%,'' + if @repository.match?(%r{^\w+://(\w+@)?}) + uri = Gem::URI(@repository).normalize.to_s.sub %r{/$},"" uri.sub(/\A(\w+)/) { $1.downcase } else @repository end - Digest::SHA1.hexdigest normalized + OpenSSL::Digest::SHA1.hexdigest normalized end - end - diff --git a/lib/rubygems/source/installed.rb b/lib/rubygems/source/installed.rb index 6d343c2439..f5c96fee51 100644 --- a/lib/rubygems/source/installed.rb +++ b/lib/rubygems/source/installed.rb @@ -1,8 +1,9 @@ +# frozen_string_literal: true + ## # Represents an installed gem. This is used for dependency resolution. class Gem::Source::Installed < Gem::Source - def initialize # :nodoc: @uri = nil end @@ -10,26 +11,29 @@ class Gem::Source::Installed < Gem::Source ## # Installed sources sort before all other sources - def <=> other + def <=>(other) case other - when Gem::Source::Lock, + when Gem::Source::Git, + Gem::Source::Lock, Gem::Source::Vendor then -1 when Gem::Source::Installed then 0 when Gem::Source then 1 - else - nil end end ## # We don't need to download an installed gem - def download spec, path + def download(spec, path) nil end + def pretty_print(q) # :nodoc: + q.object_group(self) do + q.text "[Installed]" + end + end end - diff --git a/lib/rubygems/source/local.rb b/lib/rubygems/source/local.rb index 8057921163..4bef31a265 100644 --- a/lib/rubygems/source/local.rb +++ b/lib/rubygems/source/local.rb @@ -1,19 +1,21 @@ +# frozen_string_literal: true + ## # The local source finds gems in the current directory for fulfilling # dependencies. class Gem::Source::Local < Gem::Source - def initialize # :nodoc: @specs = nil @api_uri = nil @uri = nil + @load_specs_names = {} end ## # Local sorts before Gem::Source and after Gem::Source::Installed - def <=> other + def <=>(other) case other when Gem::Source::Installed, Gem::Source::Lock then @@ -22,28 +24,27 @@ class Gem::Source::Local < Gem::Source 0 when Gem::Source then 1 - else - nil end end def inspect # :nodoc: - keys = @specs ? @specs.keys.sort : 'NOT LOADED' - "#<%s specs: %p>" % [self.class, keys] + keys = @specs ? @specs.keys.sort : "NOT LOADED" + format("#<%s specs: %p>", self.class, keys) end - def load_specs type # :nodoc: - names = [] + def load_specs(type) # :nodoc: + @load_specs_names[type] ||= begin + names = [] - @specs = {} + @specs = {} - Dir["*.gem"].each do |file| - begin + Dir["*.gem"].each do |file| pkg = Gem::Package.new(file) + spec = pkg.spec rescue SystemCallError, Gem::Package::FormatError # ignore else - tup = pkg.spec.name_tuple + tup = spec.name_tuple @specs[tup] = [File.expand_path(file), pkg] case type @@ -58,7 +59,7 @@ class Gem::Source::Local < Gem::Source when :latest tup = pkg.spec.name_tuple - cur = names.find { |x| x.name == tup.name } + cur = names.find {|x| x.name == tup.name } if !cur names << tup elsif cur.version < tup.version @@ -69,35 +70,37 @@ class Gem::Source::Local < Gem::Source names << pkg.spec.name_tuple end end + + names end + end - names + def find_gem(gem_name, version = Gem::Requirement.default, prerelease = false) # :nodoc: + find_all_gems(gem_name, version, prerelease).max_by(&:version) end - def find_gem gem_name, version = Gem::Requirement.default, # :nodoc: - prerelease = false + def find_all_gems(gem_name, version = Gem::Requirement.default, prerelease = false) # :nodoc: load_specs :complete found = [] @specs.each do |n, data| - if n.name == gem_name - s = data[1].spec - - if version.satisfied_by?(s.version) - if prerelease - found << s - elsif !s.version.prerelease? - found << s - end + next unless n.name == gem_name + s = data[1].spec + + if version.satisfied_by?(s.version) + if prerelease + found << s + elsif !s.version.prerelease? || version.prerelease? + found << s end end end - found.max_by { |s| s.version } + found end - def fetch_spec name # :nodoc: + def fetch_spec(name) # :nodoc: load_specs :complete if data = @specs[name] @@ -107,23 +110,26 @@ class Gem::Source::Local < Gem::Source end end - def download spec, cache_dir = nil # :nodoc: + def download(spec, cache_dir = nil) # :nodoc: load_specs :complete - @specs.each do |name, data| + @specs.each do |_name, data| return data[0] if data[1].spec == spec end raise Gem::Exception, "Unable to find file for '#{spec.full_name}'" end - def pretty_print q # :nodoc: - q.group 2, '[Local gems:', ']' do - q.breakable - q.seplist @specs.keys do |v| - q.text v.full_name + def pretty_print(q) # :nodoc: + q.object_group(self) do + q.group 2, "[Local gems:", "]" do + q.breakable + if @specs + q.seplist @specs.keys do |v| + q.text v.full_name + end + end end end end - end diff --git a/lib/rubygems/source/lock.rb b/lib/rubygems/source/lock.rb index 2ba7702bda..70849210bd 100644 --- a/lib/rubygems/source/lock.rb +++ b/lib/rubygems/source/lock.rb @@ -1,10 +1,11 @@ +# frozen_string_literal: true + ## # A Lock source wraps an installed gem's source and sorts before other sources # during dependency resolution. This allows RubyGems to prefer gems from # dependency lock files. class Gem::Source::Lock < Gem::Source - ## # The wrapped Gem::Source @@ -14,35 +15,35 @@ class Gem::Source::Lock < Gem::Source # Creates a new Lock source that wraps +source+ and moves it earlier in the # sort list. - def initialize source + def initialize(source) @wrapped = source end - def <=> other # :nodoc: + def <=>(other) # :nodoc: case other when Gem::Source::Lock then @wrapped <=> other.wrapped when Gem::Source then 1 - else - nil end end - def == other # :nodoc: - 0 == (self <=> other) + def ==(other) # :nodoc: + (self <=> other) == 0 + end + + def hash # :nodoc: + @wrapped.hash ^ 3 end ## # Delegates to the wrapped source's fetch_spec method. - def fetch_spec name_tuple + def fetch_spec(name_tuple) @wrapped.fetch_spec name_tuple end def uri # :nodoc: @wrapped.uri end - end - diff --git a/lib/rubygems/source/specific_file.rb b/lib/rubygems/source/specific_file.rb index a7b6c53542..dde1d48a21 100644 --- a/lib/rubygems/source/specific_file.rb +++ b/lib/rubygems/source/specific_file.rb @@ -1,8 +1,14 @@ +# frozen_string_literal: true + ## # A source representing a single .gem file. This is used for installation of # local gems. class Gem::Source::SpecificFile < Gem::Source + ## + # The path to the gem for this specific file. + + attr_reader :path ## # Creates a new SpecificFile for the gem in +file+ @@ -21,25 +27,26 @@ class Gem::Source::SpecificFile < Gem::Source attr_reader :spec - def load_specs *a # :nodoc: + def load_specs(*a) # :nodoc: [@name] end - def fetch_spec name # :nodoc: + def fetch_spec(name) # :nodoc: return @spec if name == @name raise Gem::Exception, "Unable to find '#{name}'" - @spec end - def download spec, dir = nil # :nodoc: + def download(spec, dir = nil) # :nodoc: return @path if spec == @spec raise Gem::Exception, "Unable to download '#{spec.full_name}'" end - def pretty_print q # :nodoc: - q.group 2, '[Local:', ']' do - q.breakable - q.text @path + def pretty_print(q) # :nodoc: + q.object_group(self) do + q.group 2, "[SpecificFile:", "]" do + q.breakable + q.text @path + end end end @@ -53,7 +60,7 @@ class Gem::Source::SpecificFile < Gem::Source # # Otherwise Gem::Source#<=> is used. - def <=> other + def <=>(other) case other when Gem::Source::SpecificFile then return nil if @spec.name != other.spec.name @@ -63,5 +70,4 @@ class Gem::Source::SpecificFile < Gem::Source super end end - end diff --git a/lib/rubygems/source/vendor.rb b/lib/rubygems/source/vendor.rb index 2d936231c1..44ef614441 100644 --- a/lib/rubygems/source/vendor.rb +++ b/lib/rubygems/source/vendor.rb @@ -1,16 +1,17 @@ +# frozen_string_literal: true + ## # This represents a vendored source that is similar to an installed gem. class Gem::Source::Vendor < Gem::Source::Installed - ## # Creates a new Vendor source for a gem that was unpacked at +path+. - def initialize path + def initialize(path) @uri = path end - def <=> other + def <=>(other) case other when Gem::Source::Lock then -1 @@ -18,10 +19,6 @@ class Gem::Source::Vendor < Gem::Source::Installed 0 when Gem::Source then 1 - else - nil end end - end - |
