lib/bundler/definition.rb in bundler-2.3.19 vs lib/bundler/definition.rb in bundler-2.3.20

- old
+ new

@@ -68,10 +68,11 @@ @dependencies = dependencies @sources = sources @unlock = unlock @optional_groups = optional_groups @remote = false + @prefer_local = false @specs = nil @ruby_version = ruby_version @gemfiles = gemfiles @lockfile = lockfile @@ -168,10 +169,17 @@ @remote = false sources.local_only! resolve end + def resolve_prefering_local! + @prefer_local = true + @remote = true + sources.remote! + resolve + end + def resolve_with_cache! sources.cached! resolve end @@ -474,10 +482,11 @@ private def reresolve last_resolve = converge_locked_specs + remove_ruby_from_platforms_if_necessary!(dependencies) expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, true) Resolver.resolve(expanded_dependencies, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms) end def filter_specs(specs, deps) @@ -514,22 +523,33 @@ @resolve = reresolve specs = resolve.materialize(dependencies) end end - unless specs["bundler"].any? - bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last - specs["bundler"] = bundler - end + bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last + specs["bundler"] = bundler specs end def precompute_source_requirements_for_indirect_dependencies? @remote && sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source? end + def pin_locally_available_names(source_requirements) + source_requirements.each_with_object({}) do |(name, original_source), new_source_requirements| + local_source = original_source.dup + local_source.local_only! + + new_source_requirements[name] = if local_source.specs.search(name).any? + local_source + else + original_source + end + end + end + def current_ruby_platform_locked? return false unless generic_local_platform == Gem::Platform::RUBY return false if Bundler.settings[:force_ruby_platform] && !@platforms.include?(Gem::Platform::RUBY) current_platform_locked? @@ -717,21 +737,29 @@ deps = @dependencies.select do |dep| specs[dep].any? {|s| s.satisfies?(dep) && (!dep.source || s.source.include?(dep.source)) } end + @specs_that_changed_sources = [] + specs.each do |s| - # Replace the locked dependency's source with the equivalent source from the Gemfile dep = @dependencies.find {|d| s.satisfies?(d) } - s.source = (dep && dep.source) || sources.get(s.source) || sources.default_source + # Replace the locked dependency's source with the equivalent source from the Gemfile + s.source = if dep && dep.source + gemfile_source = dep.source + lockfile_source = s.source - next if @unlock[:sources].include?(s.source.name) + @specs_that_changed_sources << s if gemfile_source != lockfile_source - # If the spec is from a path source and it doesn't exist anymore - # then we unlock it. + gemfile_source + else + sources.get_with_fallback(s.source) + end + next if @unlock[:sources].include?(s.source.name) + # Path sources have special logic if s.source.instance_of?(Source::Path) || s.source.instance_of?(Source::Gemspec) new_specs = begin s.source.specs rescue PathError, GitError @@ -763,11 +791,11 @@ SpecSet.new(filter_specs(converged, deps).reject {|s| @unlock[:gems].include?(s.name) }) end def metadata_dependencies @metadata_dependencies ||= [ - Dependency.new("Ruby\0", RubyVersion.system.gem_version), + Dependency.new("Ruby\0", Gem.ruby_version), Dependency.new("RubyGems\0", Gem::VERSION), ] end def expand_dependencies(dependencies, remote = false) @@ -790,23 +818,34 @@ def source_requirements # Record the specs available in each gem's source, so that those # specs will be available later when the resolver knows where to # look for that gemspec (or its dependencies) source_requirements = if precompute_source_requirements_for_indirect_dependencies? - { :default => sources.default_source }.merge(source_map.all_requirements) + all_requirements = source_map.all_requirements + all_requirements = pin_locally_available_names(all_requirements) if @prefer_local + { :default => sources.default_source }.merge(all_requirements) else { :default => Source::RubygemsAggregate.new(sources, source_map) }.merge(source_map.direct_requirements) end source_requirements.merge!(source_map.locked_requirements) unless @remote metadata_dependencies.each do |dep| source_requirements[dep.name] = sources.metadata_source end source_requirements[:default_bundler] = source_requirements["bundler"] || sources.default_source source_requirements["bundler"] = sources.metadata_source # needs to come last to override + verify_changed_sources! source_requirements end + def verify_changed_sources! + @specs_that_changed_sources.each do |s| + if s.source.specs.search(s.name).empty? + raise GemNotFound, "Could not find gem '#{s.name}' in #{s.source}" + end + end + end + def requested_groups values = groups - Bundler.settings[:without] - @optional_groups + Bundler.settings[:with] values &= Bundler.settings[:only] unless Bundler.settings[:only].empty? values end @@ -840,9 +879,20 @@ converge_specs(@originally_locked_specs).map do |locked_spec| name = locked_spec.name dep = Dependency.new(name, ">= #{locked_spec.version}") DepProxy.get_proxy(dep, locked_spec.platform) end + end + + def remove_ruby_from_platforms_if_necessary!(dependencies) + return if Bundler.frozen_bundle? || + Bundler.local_platform == Gem::Platform::RUBY || + !platforms.include?(Gem::Platform::RUBY) || + (@new_platform && platforms.last == Gem::Platform::RUBY) || + !@originally_locked_specs.incomplete_ruby_specs?(dependencies) + + remove_platform(Gem::Platform::RUBY) + add_current_platform end def source_map @source_map ||= SourceMap.new(sources, dependencies, @locked_specs) end