Given a set of Gem::Dependency
objects as needed
and a way to query the set of available specs via set
, calculates a set of ActivationRequest
objects which indicate all the specs that should be activated to meet the all the requirements.
If the DEBUG_RESOLVER
environment variable is set then debugging mode is enabled for the resolver. This will display information about the state of the resolver while a set of dependencies is being resolved.
Combines sets
into a ComposedSet
that allows specification lookup in a uniform manner. If one of the sets
is itself a ComposedSet
its sets are flattened into the result ComposedSet
.
# File rubygems/resolver.rb, line 62 def self.compose_sets *sets sets.compact! sets = sets.map do |set| case set when Gem::Resolver::BestSet then set when Gem::Resolver::ComposedSet then set.sets else set end end.flatten case sets.length when 0 then raise ArgumentError, 'one set in the composition must be non-nil' when 1 then sets.first else Gem::Resolver::ComposedSet.new(*sets) end end
Creates a Resolver
that queries only against the already installed gems for the needed
dependencies.
# File rubygems/resolver.rb, line 90 def self.for_current_gems needed new needed, Gem::Resolver::CurrentSet.new end
Create Resolver
object which will resolve the tree starting with needed
Dependency objects.
set
is an object that provides where to look for specifications to satisfy the Dependencies. This defaults to IndexSet
, which will query rubygems.org.
# File rubygems/resolver.rb, line 102 def initialize needed, set = nil @set = set || Gem::Resolver::IndexSet.new @needed = needed @development = false @development_shallow = false @ignore_dependencies = false @missing = [] @skip_gems = {} @soft_missing = false @stats = Gem::Resolver::Stats.new end
# File rubygems/resolver.rb, line 271 def allow_missing?(dependency) @missing << dependency @soft_missing end
# File rubygems/resolver.rb, line 257 def dependencies_for(specification) return [] if @ignore_dependencies spec = specification.spec requests(spec, specification) end
# File rubygems/resolver.rb, line 267 def name_for(dependency) dependency.name end
# File rubygems/resolver.rb, line 173 def output @output ||= debug? ? $stdout : File.open(Gem::Util::NULL_DEVICE, 'w') end
# File rubygems/resolver.rb, line 263 def requirement_satisfied_by?(requirement, activated, spec) requirement.matches_spec? spec end
Proceed with resolution! Returns an array of ActivationRequest
objects.
# File rubygems/resolver.rb, line 186 def resolve locking_dg = Molinillo::DependencyGraph.new Molinillo::Resolver.new(self, self).resolve(@needed.map { |d| DependencyRequest.new d, nil }, locking_dg).tsort.map(&:payload).compact rescue Molinillo::VersionConflict => e conflict = e.conflicts.values.first raise Gem::DependencyResolutionError, Conflict.new(conflict.requirement_trees.first.first, conflict.existing, conflict.requirement) ensure @output.close if defined?(@output) and !debug? end
# File rubygems/resolver.rb, line 225 def search_for(dependency) possibles, all = find_possible(dependency) if !@soft_missing && possibles.empty? @missing << dependency exc = Gem::UnsatisfiableDependencyError.new dependency, all exc.errors = @set.errors raise exc end sources = [] groups = Hash.new { |hash, key| hash[key] = [] } # create groups & sources in the same loop sources = possibles.map { |spec| source = spec.source groups[source] << spec source }.uniq.reverse activation_requests = [] sources.each do |source| groups[source]. sort_by { |spec| [spec.version, Gem::Platform.local =~ spec.platform ? 1 : 0] }. map { |spec| ActivationRequest.new spec, dependency, [] }. each { |activation_request| activation_requests << activation_request } end activation_requests end
# File rubygems/resolver.rb, line 276 def sort_dependencies(dependencies, activated, conflicts) dependencies.sort_by.with_index do |dependency, i| name = name_for(dependency) [ activated.vertex_named(name).payload ? 0 : 1, amount_constrained(dependency), conflicts[name] ? 0 : 1, activated.vertex_named(name).payload ? 0 : search_for(dependency).count, i # for stable sort ] end end