summaryrefslogtreecommitdiff
path: root/lib/bundler/resolver.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/bundler/resolver.rb')
-rw-r--r--lib/bundler/resolver.rb62
1 files changed, 33 insertions, 29 deletions
diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb
index 0c11c83b72..585b8667ad 100644
--- a/lib/bundler/resolver.rb
+++ b/lib/bundler/resolver.rb
@@ -17,14 +17,15 @@ module Bundler
# ==== Returns
# <GemBundle>,nil:: If the list of dependencies can be resolved, a
# collection of gemspecs is returned. Otherwise, nil is returned.
- def self.resolve(requirements, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil)
+ def self.resolve(requirements, index, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil)
base = SpecSet.new(base) unless base.is_a?(SpecSet)
- resolver = new(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
+ resolver = new(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
result = resolver.start(requirements)
SpecSet.new(result)
end
- def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
+ def initialize(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
+ @index = index
@source_requirements = source_requirements
@base = base
@resolver = Molinillo::Resolver.new(self, self)
@@ -39,7 +40,7 @@ module Bundler
@resolving_only_for_ruby = platforms == [Gem::Platform::RUBY]
@gem_version_promoter = gem_version_promoter
@use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
- @no_aggregate_global_source = @source_requirements[:global].nil?
+ @lockfile_uses_separate_rubygems_sources = Bundler.feature_flag.disable_multisource?
@variant_specific_names = []
@generic_names = ["Ruby\0", "RubyGems\0"]
@@ -124,7 +125,8 @@ module Bundler
dependency = dependency_proxy.dep
name = dependency.name
search_result = @search_for[dependency_proxy] ||= begin
- results = results_for(dependency, @base[name])
+ index = index_for(dependency)
+ results = index.search(dependency, @base[name])
if vertex = @base_dg.vertex_named(name)
locked_requirement = vertex.payload.requirement
@@ -193,26 +195,23 @@ module Bundler
search_result
end
- def index_for(dependency, base)
+ def index_for(dependency)
source = @source_requirements[dependency.name]
if source
source.specs
- elsif @no_aggregate_global_source
- dependency.all_sources.find(-> { Index.new }) do |s|
- idx = s.specs
- results = idx.search(dependency, base)
- next if results.empty? || results == base
- return idx
+ elsif @lockfile_uses_separate_rubygems_sources
+ Index.build do |idx|
+ if dependency.all_sources
+ dependency.all_sources.each {|s| idx.add_source(s.specs) if s }
+ else
+ idx.add_source @source_requirements[:default].specs
+ end
end
else
- @source_requirements[:global]
+ @index
end
end
- def results_for(dependency, base)
- index_for(dependency, base).search(dependency, base)
- end
-
def name_for(dependency)
dependency.name
end
@@ -239,13 +238,11 @@ module Bundler
def relevant_sources_for_vertex(vertex)
if vertex.root?
- [@source_requirements[vertex.name]].compact
- elsif @no_aggregate_global_source
+ [@source_requirements[vertex.name]]
+ elsif @lockfile_uses_separate_rubygems_sources
vertex.recursive_predecessors.map do |v|
@source_requirements[v.name]
- end.compact << @source_requirements[:default]
- else
- []
+ end << @source_requirements[:default]
end
end
@@ -286,7 +283,7 @@ module Bundler
if (base = @base[dependency.name]) && !base.empty?
dependency.requirement.satisfied_by?(base.first.version) ? 0 : 1
else
- all = index_for(dependency, base).search(dependency.name).size
+ all = index_for(dependency).search(dependency.name).size
if all <= 1
all - 1_000_000
@@ -329,7 +326,7 @@ module Bundler
"The source does not contain any versions of '#{name}'"
end
else
- message = "Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in any of the gem sources " \
+ message = "Could not find gem '#{requirement}' in any of the gem sources " \
"listed in your Gemfile#{cache_message}."
end
raise GemNotFound, message
@@ -414,8 +411,14 @@ module Bundler
relevant_sources = if conflict.requirement.source
[conflict.requirement.source]
- else
+ elsif conflict.requirement.all_sources
conflict.requirement.all_sources
+ elsif @lockfile_uses_separate_rubygems_sources
+ # every conflict should have an explicit group of sources when we
+ # enforce strict pinning
+ raise "no source set for #{conflict}"
+ else
+ []
end.compact.map(&:to_s).uniq.sort
metadata_requirement = name.end_with?("\0")
@@ -452,8 +455,7 @@ module Bundler
def validate_resolved_specs!(resolved_specs)
resolved_specs.each do |v|
name = v.name
- sources = relevant_sources_for_vertex(v)
- next unless sources.any?
+ next unless sources = relevant_sources_for_vertex(v)
sources.compact!
if default_index = sources.index(@source_requirements[:default])
sources.delete_at(default_index)
@@ -462,12 +464,14 @@ module Bundler
sources.uniq!
next if sources.size <= 1
+ multisource_disabled = Bundler.feature_flag.disable_multisource?
+
msg = ["The gem '#{name}' was found in multiple relevant sources."]
msg.concat sources.map {|s| " * #{s}" }.sort
- msg << "You #{@no_aggregate_global_source ? :must : :should} add this gem to the source block for the source you wish it to be installed from."
+ msg << "You #{multisource_disabled ? :must : :should} add this gem to the source block for the source you wish it to be installed from."
msg = msg.join("\n")
- raise SecurityError, msg if @no_aggregate_global_source
+ raise SecurityError, msg if multisource_disabled
Bundler.ui.warn "Warning: #{msg}"
end
end