diff options
Diffstat (limited to 'lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb')
-rw-r--r-- | lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb index 712864495f..cc572b411a 100644 --- a/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb +++ b/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb @@ -12,13 +12,15 @@ module Gem::Resolver::Molinillo # @attr [Object] locked_requirement the relevant locking requirement. # @attr [Array<Array<Object>>] requirement_trees the different requirement # trees that led to every requirement for the conflicting name. + # @attr [{String=>Object}] activated_by_name the already-activated specs. Conflict = Struct.new( :requirement, :requirements, :existing, :possibility, :locked_requirement, - :requirement_trees + :requirement_trees, + :activated_by_name ) # @return [SpecificationProvider] the provider that knows about @@ -164,7 +166,7 @@ module Gem::Resolver::Molinillo # @return [DependencyState] the initial state for the resolution def initial_state graph = DependencyGraph.new.tap do |dg| - original_requested.each { |r| dg.add_root_vertex(name_for(r), nil).tap { |v| v.explicit_requirements << r } } + original_requested.each { |r| dg.add_vertex(name_for(r), nil, true).tap { |v| v.explicit_requirements << r } } end requirements = sort_dependencies(original_requested, graph, {}) @@ -216,7 +218,7 @@ module Gem::Resolver::Molinillo return nil unless requirement seen = false state = states.reverse_each.find do |s| - seen ||= s.requirement == requirement + seen ||= s.requirement == requirement || s.requirements.include?(requirement) seen && s.requirement != requirement && !s.requirements.include?(requirement) end state && state.requirement @@ -250,21 +252,23 @@ module Gem::Resolver::Molinillo name_for_explicit_dependency_source => vertex.explicit_requirements, name_for_locking_dependency_source => Array(locked_requirement_named(name)), } - vertex.incoming_edges.each { |edge| (requirements[edge.origin.payload] ||= []).unshift(*edge.requirements) } + vertex.incoming_edges.each { |edge| (requirements[edge.origin.payload] ||= []).unshift(edge.requirement) } conflicts[name] = Conflict.new( requirement, Hash[requirements.select { |_, r| !r.empty? }], vertex.payload, possibility, locked_requirement_named(name), - requirement_trees + requirement_trees, + Hash[activated.map { |v| [v.name, v.payload] }.select(&:last)] ) end # @return [Array<Array<Object>>] The different requirement # trees that led to every requirement for the current spec. def requirement_trees - activated.vertex_named(name).requirements.map { |r| requirement_tree_for(r) } + vertex = activated.vertex_named(name) + vertex.requirements.map { |r| requirement_tree_for(r) } end # @return [Array<Object>] the list of requirements that led to @@ -322,7 +326,7 @@ module Gem::Resolver::Molinillo existing_spec = existing_node.payload if requirement_satisfied_by?(requirement, activated, existing_spec) new_requirements = requirements.dup - push_state_for_requirements(new_requirements) + push_state_for_requirements(new_requirements, false) else return if attempt_to_swap_possibility create_conflict @@ -389,17 +393,17 @@ module Gem::Resolver::Molinillo def require_nested_dependencies_for(activated_spec) nested_dependencies = dependencies_for(activated_spec) debug(depth) { "Requiring nested dependencies (#{nested_dependencies.map(&:to_s).join(', ')})" } - nested_dependencies.each { |d| activated.add_child_vertex name_for(d), nil, [name_for(activated_spec)], d } + nested_dependencies.each { |d| activated.add_child_vertex(name_for(d), nil, [name_for(activated_spec)], d) } - push_state_for_requirements(requirements + nested_dependencies) + push_state_for_requirements(requirements + nested_dependencies, nested_dependencies.size > 0) end # Pushes a new {DependencyState} that encapsulates both existing and new # requirements # @param [Array] new_requirements # @return [void] - def push_state_for_requirements(new_requirements, new_activated = activated.dup) - new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts) + def push_state_for_requirements(new_requirements, requires_sort = true, new_activated = activated.dup) + new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts) if requires_sort new_requirement = new_requirements.shift new_name = new_requirement ? name_for(new_requirement) : '' possibilities = new_requirement ? search_for(new_requirement) : [] @@ -420,7 +424,7 @@ module Gem::Resolver::Molinillo def handle_missing_or_push_dependency_state(state) if state.requirement && state.possibilities.empty? && allow_missing?(state.requirement) state.activated.detach_vertex_named(state.name) - push_state_for_requirements(state.requirements, state.activated) + push_state_for_requirements(state.requirements.dup, false, state.activated) else states.push state end |