diff options
Diffstat (limited to 'lib/bundler/lazy_specification.rb')
-rw-r--r-- | lib/bundler/lazy_specification.rb | 69 |
1 files changed, 42 insertions, 27 deletions
diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb index dccfe48bba..8669e021c2 100644 --- a/lib/bundler/lazy_specification.rb +++ b/lib/bundler/lazy_specification.rb @@ -4,39 +4,60 @@ require_relative "force_platform" module Bundler class LazySpecification + include MatchMetadata include MatchPlatform include ForcePlatform - attr_reader :name, :version, :dependencies, :platform - attr_accessor :source, :remote, :force_ruby_platform + attr_reader :name, :version, :platform + attr_accessor :source, :remote, :force_ruby_platform, :dependencies, :required_ruby_version, :required_rubygems_version + + alias_method :runtime_dependencies, :dependencies + + def self.from_spec(s) + lazy_spec = new(s.name, s.version, s.platform, s.source) + lazy_spec.dependencies = s.dependencies + lazy_spec.required_ruby_version = s.required_ruby_version + lazy_spec.required_rubygems_version = s.required_rubygems_version + lazy_spec + end def initialize(name, version, platform, source = nil) @name = name @version = version @dependencies = [] + @required_ruby_version = Gem::Requirement.default + @required_rubygems_version = Gem::Requirement.default @platform = platform || Gem::Platform::RUBY @source = source @force_ruby_platform = default_force_ruby_platform end def full_name - if platform == Gem::Platform::RUBY + @full_name ||= if platform == Gem::Platform::RUBY "#{@name}-#{@version}" else "#{@name}-#{@version}-#{platform}" end end + def lock_name + @lock_name ||= name_tuple.lock_name + end + + def name_tuple + Gem::NameTuple.new(@name, @version, @platform) + end + def ==(other) - identifier == other.identifier + full_name == other.full_name end def eql?(other) - identifier.eql?(other.identifier) + full_name.eql?(other.full_name) end def hash - identifier.hash + full_name.hash end ## @@ -61,12 +82,7 @@ module Bundler def to_lock out = String.new - - if platform == Gem::Platform::RUBY - out << " #{name} (#{version})\n" - else - out << " #{name} (#{version}-#{platform})\n" - end + out << " #{lock_name}\n" dependencies.sort_by(&:to_s).uniq.each do |dep| next if dep.type == :development @@ -89,7 +105,7 @@ module Bundler installable_candidates = GemHelpers.select_best_platform_match(matching_specs, target_platform) - specification = __materialize__(installable_candidates) + specification = __materialize__(installable_candidates, fallback_to_non_installable: false) return specification unless specification.nil? if target_platform != platform @@ -102,13 +118,16 @@ module Bundler __materialize__(candidates) end - def __materialize__(candidates) + # If in frozen mode, we fallback to a non-installable candidate because by + # doing this we avoid re-resolving and potentially end up changing the + # lock file, which is not allowed. In that case, we will give a proper error + # about the mismatch higher up the stack, right before trying to install the + # bad gem. + def __materialize__(candidates, fallback_to_non_installable: Bundler.frozen_bundle?) search = candidates.reverse.find do |spec| - spec.is_a?(StubSpecification) || - (spec.matches_current_ruby? && - spec.matches_current_rubygems?) + spec.is_a?(StubSpecification) || spec.matches_current_metadata? end - if search.nil? && Bundler.frozen_bundle? + if search.nil? && fallback_to_non_installable search = candidates.last else search.dependencies = dependencies if search && search.full_name == full_name && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification)) @@ -117,15 +136,7 @@ module Bundler end def to_s - @__to_s ||= if platform == Gem::Platform::RUBY - "#{name} (#{version})" - else - "#{name} (#{version}-#{platform})" - end - end - - def identifier - @__identifier ||= [name, version, platform.to_s] + lock_name end def git_version @@ -133,6 +144,10 @@ module Bundler " #{source.revision[0..6]}" end + def force_ruby_platform! + @force_ruby_platform = true + end + private def use_exact_resolved_specifications? |