diff options
Diffstat (limited to 'lib/rubygems/resolver/installer_set.rb')
-rw-r--r-- | lib/rubygems/resolver/installer_set.rb | 64 |
1 files changed, 57 insertions, 7 deletions
diff --git a/lib/rubygems/resolver/installer_set.rb b/lib/rubygems/resolver/installer_set.rb index b0e4ce5a37..60181315b0 100644 --- a/lib/rubygems/resolver/installer_set.rb +++ b/lib/rubygems/resolver/installer_set.rb @@ -26,6 +26,12 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set attr_reader :remote_set # :nodoc: ## + # Ignore ruby & rubygems specification constraints. + # + + attr_accessor :force # :nodoc: + + ## # Creates a new InstallerSet that will look for gems in +domain+. def initialize(domain) @@ -41,6 +47,7 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set @local = {} @local_source = Gem::Source::Local.new @remote_set = Gem::Resolver::BestSet.new + @force = false @specs = {} end @@ -63,15 +70,30 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set Gem::Platform.local === s.platform end - if found.empty? - exc = Gem::UnsatisfiableDependencyError.new request - exc.errors = errors - - raise exc + found = found.sort_by do |s| + [s.version, s.platform == Gem::Platform::RUBY ? -1 : 1] end - newest = found.max_by do |s| - [s.version, s.platform == Gem::Platform::RUBY ? -1 : 1] + newest = found.last + + unless @force + found_matching_metadata = found.select do |spec| + metadata_satisfied?(spec) + end + + if found_matching_metadata.empty? + if newest + ensure_required_ruby_version_met(newest.spec) + ensure_required_rubygems_version_met(newest.spec) + else + exc = Gem::UnsatisfiableDependencyError.new request + exc.errors = errors + + raise exc + end + else + newest = found_matching_metadata.last + end end @always_install << newest.spec @@ -221,4 +243,32 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set @domain = :local unless remote end end + + private + + def metadata_satisfied?(spec) + spec.required_ruby_version.satisfied_by?(Gem.ruby_version) && + spec.required_rubygems_version.satisfied_by?(Gem.rubygems_version) + end + + def ensure_required_ruby_version_met(spec) # :nodoc: + if rrv = spec.required_ruby_version + ruby_version = Gem.ruby_version + unless rrv.satisfied_by? ruby_version + raise Gem::RuntimeRequirementNotMetError, + "#{spec.full_name} requires Ruby version #{rrv}. The current ruby version is #{ruby_version}." + end + end + end + + def ensure_required_rubygems_version_met(spec) # :nodoc: + if rrgv = spec.required_rubygems_version + unless rrgv.satisfied_by? Gem.rubygems_version + rg_version = Gem::VERSION + raise Gem::RuntimeRequirementNotMetError, + "#{spec.full_name} requires RubyGems version #{rrgv}. The current RubyGems version is #{rg_version}. " + + "Try 'gem update --system' to update RubyGems itself." + end + end + end end |