summaryrefslogtreecommitdiff
path: root/lib/rubygems/resolver
diff options
context:
space:
mode:
authorhsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-09-14 03:30:02 +0000
committerhsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-09-14 03:30:02 +0000
commit4de117a61517e839f2c45eaf45d56fc243d6d5b2 (patch)
tree7cb5af7a7eb513e5dddf5e343746b1611e628387 /lib/rubygems/resolver
parente548c09d429a5136285ea81aed418685359ed124 (diff)
* lib/rubygems: Update to RubyGems 2.4.1 master(713ab65)
Complete history at: https://github.com/rubygems/rubygems/blob/master/History.txt#L3-L216 * test/rubygems: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47582 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/rubygems/resolver')
-rw-r--r--lib/rubygems/resolver/activation_request.rb7
-rw-r--r--lib/rubygems/resolver/api_set.rb14
-rw-r--r--lib/rubygems/resolver/api_specification.rb6
-rw-r--r--lib/rubygems/resolver/best_set.rb28
-rw-r--r--lib/rubygems/resolver/composed_set.rb16
-rw-r--r--lib/rubygems/resolver/conflict.rb52
-rw-r--r--lib/rubygems/resolver/dependency_request.rb21
-rw-r--r--lib/rubygems/resolver/git_set.rb2
-rw-r--r--lib/rubygems/resolver/git_specification.rb26
-rw-r--r--lib/rubygems/resolver/index_set.rb6
-rw-r--r--lib/rubygems/resolver/installed_specification.rb20
-rw-r--r--lib/rubygems/resolver/installer_set.rb94
-rw-r--r--lib/rubygems/resolver/local_specification.rb25
-rw-r--r--lib/rubygems/resolver/lock_set.rb22
-rw-r--r--lib/rubygems/resolver/lock_specification.rb28
-rw-r--r--lib/rubygems/resolver/set.rb14
-rw-r--r--lib/rubygems/resolver/spec_specification.rb2
-rw-r--r--lib/rubygems/resolver/specification.rb25
-rw-r--r--lib/rubygems/resolver/vendor_set.rb4
-rw-r--r--lib/rubygems/resolver/vendor_specification.rb2
20 files changed, 378 insertions, 36 deletions
diff --git a/lib/rubygems/resolver/activation_request.rb b/lib/rubygems/resolver/activation_request.rb
index 2d48cfa927..56c6363e4f 100644
--- a/lib/rubygems/resolver/activation_request.rb
+++ b/lib/rubygems/resolver/activation_request.rb
@@ -39,6 +39,13 @@ class Gem::Resolver::ActivationRequest
end
##
+ # Is this activation request for a development dependency?
+
+ def development?
+ @request.development?
+ end
+
+ ##
# Downloads a gem at +path+ and returns the file path.
def download path
diff --git a/lib/rubygems/resolver/api_set.rb b/lib/rubygems/resolver/api_set.rb
index 5475e626e6..dda3579878 100644
--- a/lib/rubygems/resolver/api_set.rb
+++ b/lib/rubygems/resolver/api_set.rb
@@ -34,6 +34,8 @@ class Gem::Resolver::APISet < Gem::Resolver::Set
@data = Hash.new { |h,k| h[k] = [] }
@source = Gem::Source.new @uri
+
+ @to_fetch = []
end
##
@@ -45,6 +47,10 @@ class Gem::Resolver::APISet < Gem::Resolver::Set
return res unless @remote
+ if @to_fetch.include?(req.name)
+ prefetch_now
+ end
+
versions(req.name).each do |ver|
if req.dependency.match? req.name, ver[:number]
res << Gem::Resolver::APISpecification.new(self, ver)
@@ -61,9 +67,13 @@ class Gem::Resolver::APISet < Gem::Resolver::Set
def prefetch reqs
return unless @remote
names = reqs.map { |r| r.dependency.name }
- needed = names - @data.keys
+ needed = names - @data.keys - @to_fetch
+
+ @to_fetch += needed
+ end
- return if needed.empty?
+ def prefetch_now
+ needed, @to_fetch = @to_fetch, []
uri = @dep_uri + "?gems=#{needed.sort.join ','}"
str = Gem::RemoteFetcher.fetcher.fetch_path uri
diff --git a/lib/rubygems/resolver/api_specification.rb b/lib/rubygems/resolver/api_specification.rb
index 67052af82e..bbd5a6427b 100644
--- a/lib/rubygems/resolver/api_specification.rb
+++ b/lib/rubygems/resolver/api_specification.rb
@@ -34,6 +34,12 @@ class Gem::Resolver::APISpecification < Gem::Resolver::Specification
@dependencies == other.dependencies
end
+ def fetch_development_dependencies # :nodoc:
+ spec = source.fetch_spec Gem::NameTuple.new @name, @version, @platform
+
+ @dependencies = spec.dependencies
+ end
+
def installable_platform? # :nodoc:
Gem::Platform.match @platform
end
diff --git a/lib/rubygems/resolver/best_set.rb b/lib/rubygems/resolver/best_set.rb
index 20bb94827b..7e2d7e2647 100644
--- a/lib/rubygems/resolver/best_set.rb
+++ b/lib/rubygems/resolver/best_set.rb
@@ -28,6 +28,10 @@ class Gem::Resolver::BestSet < Gem::Resolver::ComposedSet
pick_sets if @remote and @sets.empty?
super
+ rescue Gem::RemoteFetcher::FetchError => e
+ replace_failed_api_set e
+
+ retry
end
def prefetch reqs # :nodoc:
@@ -46,5 +50,29 @@ class Gem::Resolver::BestSet < Gem::Resolver::ComposedSet
end
end
+ ##
+ # Replaces a failed APISet for the URI in +error+ with an IndexSet.
+ #
+ # If no matching APISet can be found the original +error+ is raised.
+ #
+ # The calling method must retry the exception to repeat the lookup.
+
+ def replace_failed_api_set error # :nodoc:
+ uri = error.uri
+ uri = URI uri unless URI === uri
+ uri.query = nil
+
+ raise error unless api_set = @sets.find { |set|
+ Gem::Resolver::APISet === set and set.dep_uri == uri
+ }
+
+ index_set = Gem::Resolver::IndexSet.new api_set.source
+
+ @sets.map! do |set|
+ next set unless set == api_set
+ index_set
+ end
+ end
+
end
diff --git a/lib/rubygems/resolver/composed_set.rb b/lib/rubygems/resolver/composed_set.rb
index 6f912b0afe..5b08f128ed 100644
--- a/lib/rubygems/resolver/composed_set.rb
+++ b/lib/rubygems/resolver/composed_set.rb
@@ -22,6 +22,18 @@ class Gem::Resolver::ComposedSet < Gem::Resolver::Set
end
##
+ # When +allow_prerelease+ is set to +true+ prereleases gems are allowed to
+ # match dependencies.
+
+ def prerelease= allow_prerelease
+ super
+
+ sets.each do |set|
+ set.prerelease = allow_prerelease
+ end
+ end
+
+ ##
# Sets the remote network access for all composed sets.
def remote= remote
@@ -30,6 +42,10 @@ class Gem::Resolver::ComposedSet < Gem::Resolver::Set
@sets.each { |set| set.remote = remote }
end
+ def errors
+ @errors + @sets.map { |set| set.errors }.flatten
+ end
+
##
# Finds all specs matching +req+ in all sets.
diff --git a/lib/rubygems/resolver/conflict.rb b/lib/rubygems/resolver/conflict.rb
index 8830e8d1fb..902c286b6b 100644
--- a/lib/rubygems/resolver/conflict.rb
+++ b/lib/rubygems/resolver/conflict.rb
@@ -52,11 +52,40 @@ class Gem::Resolver::Conflict
def explanation
activated = @activated.spec.full_name
- requirement = @failed_dep.dependency.requirement
+ dependency = @failed_dep.dependency
+ requirement = dependency.requirement
+ alternates = dependency.matching_specs.map { |spec| spec.full_name }
- " Activated %s via:\n %s\n instead of (%s) via:\n %s\n" % [
- activated, request_path(@activated).join(', '),
- requirement, request_path(requester).join(', '),
+ unless alternates.empty? then
+ matching = <<-MATCHING.chomp
+
+ Gems matching %s:
+ %s
+ MATCHING
+
+ matching = matching % [
+ dependency,
+ alternates.join(', '),
+ ]
+ end
+
+ explanation = <<-EXPLANATION
+ Activated %s
+ which does not match conflicting dependency (%s)
+
+ Conflicting dependency chains:
+ %s
+
+ versus:
+ %s
+%s
+ EXPLANATION
+
+ explanation % [
+ activated, requirement,
+ request_path(@activated).reverse.join(", depends on\n "),
+ request_path(@failed_dep).reverse.join(", depends on\n "),
+ matching,
]
end
@@ -95,10 +124,19 @@ class Gem::Resolver::Conflict
path = []
while current do
- requirement = current.request.dependency.requirement
- path << "#{current.spec.full_name} (#{requirement})"
+ case current
+ when Gem::Resolver::ActivationRequest then
+ path <<
+ "#{current.request.dependency}, #{current.spec.version} activated"
+
+ current = current.parent
+ when Gem::Resolver::DependencyRequest then
+ path << "#{current.dependency}"
- current = current.parent
+ current = current.requester
+ else
+ raise Gem::Exception, "[BUG] unknown request class #{current.class}"
+ end
end
path = ['user request (gem command or Gemfile)'] if path.empty?
diff --git a/lib/rubygems/resolver/dependency_request.rb b/lib/rubygems/resolver/dependency_request.rb
index 1d51db4945..79690bec4c 100644
--- a/lib/rubygems/resolver/dependency_request.rb
+++ b/lib/rubygems/resolver/dependency_request.rb
@@ -35,7 +35,26 @@ class Gem::Resolver::DependencyRequest
end
##
- # Does this dependency request match +spec+
+ # Is this dependency a development dependency?
+
+ def development?
+ @dependency.type == :development
+ end
+
+ ##
+ # Does this dependency request match +spec+?
+ #
+ # NOTE: #match? only matches prerelease versions when #dependency is a
+ # prerelease dependency.
+
+ def match? spec, allow_prerelease = false
+ @dependency.match? spec, nil, allow_prerelease
+ end
+
+ ##
+ # Does this dependency request match +spec+?
+ #
+ # NOTE: #matches_spec? matches prerelease versions. See also #match?
def matches_spec?(spec)
@dependency.matches_spec? spec
diff --git a/lib/rubygems/resolver/git_set.rb b/lib/rubygems/resolver/git_set.rb
index d32710e3d6..5f1b368ac1 100644
--- a/lib/rubygems/resolver/git_set.rb
+++ b/lib/rubygems/resolver/git_set.rb
@@ -80,7 +80,7 @@ class Gem::Resolver::GitSet < Gem::Resolver::Set
prefetch nil
specs.values.select do |spec|
- req.matches_spec? spec
+ req.match? spec
end
end
diff --git a/lib/rubygems/resolver/git_specification.rb b/lib/rubygems/resolver/git_specification.rb
index 113e7ea9de..55e180e525 100644
--- a/lib/rubygems/resolver/git_specification.rb
+++ b/lib/rubygems/resolver/git_specification.rb
@@ -12,11 +12,15 @@ class Gem::Resolver::GitSpecification < Gem::Resolver::SpecSpecification
@source == other.source
end
+ def add_dependency dependency # :nodoc:
+ spec.dependencies << dependency
+ end
+
##
# Installing a git gem only involves building the extensions and generating
# the executables.
- def install options
+ def install options = {}
require 'rubygems/installer'
installer = Gem::Installer.new '', options
@@ -31,5 +35,25 @@ class Gem::Resolver::GitSpecification < Gem::Resolver::SpecSpecification
installer.run_post_install_hooks
end
+ def pretty_print q # :nodoc:
+ q.group 2, '[GitSpecification', ']' do
+ q.breakable
+ q.text "name: #{name}"
+
+ q.breakable
+ q.text "version: #{version}"
+
+ q.breakable
+ q.text 'dependencies:'
+ q.breakable
+ q.pp dependencies
+
+ q.breakable
+ q.text "source:"
+ q.breakable
+ q.pp @source
+ end
+ end
+
end
diff --git a/lib/rubygems/resolver/index_set.rb b/lib/rubygems/resolver/index_set.rb
index ef01f0f0ad..7c56c2bf99 100644
--- a/lib/rubygems/resolver/index_set.rb
+++ b/lib/rubygems/resolver/index_set.rb
@@ -18,7 +18,9 @@ class Gem::Resolver::IndexSet < Gem::Resolver::Set
@all = Hash.new { |h,k| h[k] = [] }
- list, = @f.available_specs :released
+ list, errors = @f.available_specs :complete
+
+ @errors.concat errors
list.each do |uri, specs|
specs.each do |n|
@@ -41,7 +43,7 @@ class Gem::Resolver::IndexSet < Gem::Resolver::Set
name = req.dependency.name
@all[name].each do |uri, n|
- if req.dependency.match? n then
+ if req.match? n, @prerelease then
res << Gem::Resolver::IndexSpecification.new(
self, n.name, n.version, uri, n.platform)
end
diff --git a/lib/rubygems/resolver/installed_specification.rb b/lib/rubygems/resolver/installed_specification.rb
index a9438129fb..2a2b89a6c2 100644
--- a/lib/rubygems/resolver/installed_specification.rb
+++ b/lib/rubygems/resolver/installed_specification.rb
@@ -14,7 +14,7 @@ class Gem::Resolver::InstalledSpecification < Gem::Resolver::SpecSpecification
# This is a null install as this specification is already installed.
# +options+ are ignored.
- def install options
+ def install options = {}
yield nil
end
@@ -29,6 +29,24 @@ class Gem::Resolver::InstalledSpecification < Gem::Resolver::SpecSpecification
super
end
+ def pretty_print q # :nodoc:
+ q.group 2, '[InstalledSpecification', ']' do
+ q.breakable
+ q.text "name: #{name}"
+
+ q.breakable
+ q.text "version: #{version}"
+
+ q.breakable
+ q.text "platform: #{platform}"
+
+ q.breakable
+ q.text 'dependencies:'
+ q.breakable
+ q.pp spec.dependencies
+ end
+ end
+
##
# The source for this specification
diff --git a/lib/rubygems/resolver/installer_set.rb b/lib/rubygems/resolver/installer_set.rb
index 045c893fdc..f53b496dc7 100644
--- a/lib/rubygems/resolver/installer_set.rb
+++ b/lib/rubygems/resolver/installer_set.rb
@@ -21,6 +21,11 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
attr_accessor :ignore_installed # :nodoc:
##
+ # The remote_set looks up remote gems for installation.
+
+ attr_reader :remote_set # :nodoc:
+
+ ##
# Creates a new InstallerSet that will look for gems in +domain+.
def initialize domain
@@ -34,11 +39,53 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
@always_install = []
@ignore_dependencies = false
@ignore_installed = false
+ @local = {}
@remote_set = Gem::Resolver::BestSet.new
@specs = {}
end
##
+ # Looks up the latest specification for +dependency+ and adds it to the
+ # always_install list.
+
+ def add_always_install dependency
+ request = Gem::Resolver::DependencyRequest.new dependency, nil
+
+ found = find_all request
+
+ found.delete_if { |s|
+ s.version.prerelease? and not s.local?
+ } unless dependency.prerelease?
+
+ found = found.select do |s|
+ Gem::Source::SpecificFile === s.source or
+ Gem::Platform::RUBY == s.platform or
+ Gem::Platform.local === s.platform
+ end
+
+ if found.empty? then
+ exc = Gem::UnsatisfiableDependencyError.new request
+ exc.errors = errors
+
+ raise exc
+ end
+
+ newest = found.max_by do |s|
+ [s.version, s.platform == Gem::Platform::RUBY ? -1 : 1]
+ end
+
+ @always_install << newest.spec
+ end
+
+ ##
+ # Adds a local gem requested using +dep_name+ with the given +spec+ that can
+ # be loaded and installed using the +source+.
+
+ def add_local dep_name, spec, source
+ @local[dep_name] = [spec, source]
+ end
+
+ ##
# Should local gems should be considered?
def consider_local? # :nodoc:
@@ -53,6 +100,13 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
end
##
+ # Errors encountered while resolving gems
+
+ def errors
+ @errors + @remote_set.errors
+ end
+
+ ##
# Returns an array of IndexSpecification objects matching DependencyRequest
# +req+.
@@ -62,30 +116,53 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
dep = req.dependency
return res if @ignore_dependencies and
- @always_install.none? { |spec| dep.matches_spec? spec }
+ @always_install.none? { |spec| dep.match? spec }
name = dep.name
dep.matching_specs.each do |gemspec|
- next if @always_install.include? gemspec
+ next if @always_install.any? { |spec| spec.name == gemspec.name }
res << Gem::Resolver::InstalledSpecification.new(self, gemspec)
end unless @ignore_installed
if consider_local? then
+ matching_local = @local.values.select do |spec, _|
+ req.match? spec
+ end.map do |spec, source|
+ Gem::Resolver::LocalSpecification.new self, spec, source
+ end
+
+ res.concat matching_local
+
local_source = Gem::Source::Local.new
- if spec = local_source.find_gem(name, dep.requirement) then
+ if local_spec = local_source.find_gem(name, dep.requirement) then
res << Gem::Resolver::IndexSpecification.new(
- self, spec.name, spec.version, local_source, spec.platform)
+ self, local_spec.name, local_spec.version,
+ local_source, local_spec.platform)
end
end
+ res.delete_if do |spec|
+ spec.version.prerelease? and not dep.prerelease?
+ end
+
res.concat @remote_set.find_all req if consider_remote?
res
end
+ def prefetch(reqs)
+ @remote_set.prefetch(reqs)
+ end
+
+ def prerelease= allow_prerelease
+ super
+
+ @remote_set.prerelease = allow_prerelease
+ end
+
def inspect # :nodoc:
always_install = @always_install.map { |s| s.full_name }
@@ -108,6 +185,15 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
end
end
+ ##
+ # Has a local gem for +dep_name+ been added to this set?
+
+ def local? dep_name # :nodoc:
+ spec, = @local[dep_name]
+
+ spec
+ end
+
def pretty_print q # :nodoc:
q.group 2, '[InstallerSet', ']' do
q.breakable
diff --git a/lib/rubygems/resolver/local_specification.rb b/lib/rubygems/resolver/local_specification.rb
index dcca6c736a..20a283f0ba 100644
--- a/lib/rubygems/resolver/local_specification.rb
+++ b/lib/rubygems/resolver/local_specification.rb
@@ -12,5 +12,30 @@ class Gem::Resolver::LocalSpecification < Gem::Resolver::SpecSpecification
super
end
+ def local? # :nodoc:
+ true
+ end
+
+ def pretty_print q # :nodoc:
+ q.group 2, '[LocalSpecification', ']' do
+ q.breakable
+ q.text "name: #{name}"
+
+ q.breakable
+ q.text "version: #{version}"
+
+ q.breakable
+ q.text "platform: #{platform}"
+
+ q.breakable
+ q.text 'dependencies:'
+ q.breakable
+ q.pp dependencies
+
+ q.breakable
+ q.text "source: #{@source.path}"
+ end
+ end
+
end
diff --git a/lib/rubygems/resolver/lock_set.rb b/lib/rubygems/resolver/lock_set.rb
index f4987576ec..4ede5971fb 100644
--- a/lib/rubygems/resolver/lock_set.rb
+++ b/lib/rubygems/resolver/lock_set.rb
@@ -6,13 +6,16 @@ class Gem::Resolver::LockSet < Gem::Resolver::Set
attr_reader :specs # :nodoc:
##
- # Creates a new LockSet from the given +source+
+ # Creates a new LockSet from the given +sources+
- def initialize source
+ def initialize sources
super()
- @source = Gem::Source::Lock.new source
- @specs = []
+ @sources = sources.map do |source|
+ Gem::Source::Lock.new source
+ end
+
+ @specs = []
end
##
@@ -25,13 +28,14 @@ class Gem::Resolver::LockSet < Gem::Resolver::Set
def add name, version, platform # :nodoc:
version = Gem::Version.new version
- spec =
- Gem::Resolver::LockSpecification.new self, name, version, @source,
+ specs = @sources.map do |source|
+ Gem::Resolver::LockSpecification.new self, name, version, source,
platform
+ end
- @specs << spec
+ @specs.concat specs
- spec
+ specs
end
##
@@ -40,7 +44,7 @@ class Gem::Resolver::LockSet < Gem::Resolver::Set
def find_all req
@specs.select do |spec|
- req.matches_spec? spec
+ req.match? spec
end
end
diff --git a/lib/rubygems/resolver/lock_specification.rb b/lib/rubygems/resolver/lock_specification.rb
index 4bc21b9402..0013171469 100644
--- a/lib/rubygems/resolver/lock_specification.rb
+++ b/lib/rubygems/resolver/lock_specification.rb
@@ -23,7 +23,7 @@ class Gem::Resolver::LockSpecification < Gem::Resolver::Specification
# This is a null install as a locked specification is considered installed.
# +options+ are ignored.
- def install options
+ def install options = {}
destination = options[:install_dir] || Gem.dir
if File.exist? File.join(destination, 'specifications', spec.spec_name) then
@@ -41,10 +41,36 @@ class Gem::Resolver::LockSpecification < Gem::Resolver::Specification
@dependencies << dependency
end
+ def pretty_print q # :nodoc:
+ q.group 2, '[LockSpecification', ']' do
+ q.breakable
+ q.text "name: #{@name}"
+
+ q.breakable
+ q.text "version: #{@version}"
+
+ unless @platform == Gem::Platform::RUBY then
+ q.breakable
+ q.text "platform: #{@platform}"
+ end
+
+ unless @dependencies.empty? then
+ q.breakable
+ q.text 'dependencies:'
+ q.breakable
+ q.pp @dependencies
+ end
+ end
+ end
+
##
# A specification constructed from the lockfile is returned
def spec
+ @spec ||= Gem::Specification.find { |spec|
+ spec.name == @name and spec.version == @version
+ }
+
@spec ||= Gem::Specification.new do |s|
s.name = @name
s.version = @version
diff --git a/lib/rubygems/resolver/set.rb b/lib/rubygems/resolver/set.rb
index f053b65e15..b26dc45c7b 100644
--- a/lib/rubygems/resolver/set.rb
+++ b/lib/rubygems/resolver/set.rb
@@ -9,8 +9,20 @@ class Gem::Resolver::Set
attr_accessor :remote
+ ##
+ # Errors encountered when resolving gems
+
+ attr_accessor :errors
+
+ ##
+ # When true, allows matching of requests to prerelease gems.
+
+ attr_accessor :prerelease
+
def initialize # :nodoc:
- @remote = true
+ @prerelease = false
+ @remote = true
+ @errors = []
end
##
diff --git a/lib/rubygems/resolver/spec_specification.rb b/lib/rubygems/resolver/spec_specification.rb
index 0c411bdf5f..1350e8a7ab 100644
--- a/lib/rubygems/resolver/spec_specification.rb
+++ b/lib/rubygems/resolver/spec_specification.rb
@@ -4,8 +4,6 @@
class Gem::Resolver::SpecSpecification < Gem::Resolver::Specification
- attr_reader :spec # :nodoc:
-
##
# A SpecSpecification is created for a +set+ for a Gem::Specification in
# +spec+. The +source+ is either where the +spec+ came from, or should be
diff --git a/lib/rubygems/resolver/specification.rb b/lib/rubygems/resolver/specification.rb
index d158225474..4d77293262 100644
--- a/lib/rubygems/resolver/specification.rb
+++ b/lib/rubygems/resolver/specification.rb
@@ -31,6 +31,14 @@ class Gem::Resolver::Specification
attr_reader :source
##
+ # The Gem::Specification for this Resolver::Specification.
+ #
+ # Implementers, note that #install updates @spec, so be sure to cache the
+ # Gem::Specification in @spec when overriding.
+
+ attr_reader :spec
+
+ ##
# The version of the gem for this specification.
attr_reader :version
@@ -48,6 +56,13 @@ class Gem::Resolver::Specification
end
##
+ # Fetches development dependencies if the source does not provide them by
+ # default (see APISpecification).
+
+ def fetch_development_dependencies # :nodoc:
+ end
+
+ ##
# The name and version of the specification.
#
# Unlike Gem::Specification#full_name, the platform is not included.
@@ -61,8 +76,11 @@ class Gem::Resolver::Specification
# install method yields a Gem::Installer instance, which indicates the
# gem will be installed, or +nil+, which indicates the gem is already
# installed.
+ #
+ # After installation #spec is updated to point to the just-installed
+ # specification.
- def install options
+ def install options = {}
require 'rubygems/installer'
destination = options[:install_dir] || Gem.dir
@@ -75,7 +93,7 @@ class Gem::Resolver::Specification
yield installer if block_given?
- installer.install
+ @spec = installer.install
end
##
@@ -85,5 +103,8 @@ class Gem::Resolver::Specification
Gem::Platform.match spec.platform
end
+ def local? # :nodoc:
+ false
+ end
end
diff --git a/lib/rubygems/resolver/vendor_set.rb b/lib/rubygems/resolver/vendor_set.rb
index 6e867073be..614bd05382 100644
--- a/lib/rubygems/resolver/vendor_set.rb
+++ b/lib/rubygems/resolver/vendor_set.rb
@@ -43,6 +43,8 @@ class Gem::Resolver::VendorSet < Gem::Resolver::Set
@specs[spec.name] = spec
@directories[spec] = directory
+
+ spec
end
##
@@ -51,7 +53,7 @@ class Gem::Resolver::VendorSet < Gem::Resolver::Set
def find_all req
@specs.values.select do |spec|
- req.matches_spec? spec
+ req.match? spec
end.map do |spec|
source = Gem::Source::Vendor.new @directories[spec]
Gem::Resolver::VendorSpecification.new self, spec, source
diff --git a/lib/rubygems/resolver/vendor_specification.rb b/lib/rubygems/resolver/vendor_specification.rb
index c6a8e58d9b..a99b5f3cc1 100644
--- a/lib/rubygems/resolver/vendor_specification.rb
+++ b/lib/rubygems/resolver/vendor_specification.rb
@@ -16,7 +16,7 @@ class Gem::Resolver::VendorSpecification < Gem::Resolver::SpecSpecification
# This is a null install as this gem was unpacked into a directory.
# +options+ are ignored.
- def install options
+ def install options = {}
yield nil
end