diff options
4 files changed, 45 insertions, 13 deletions
diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb b/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb index 2cf1b60b12..0e8e437240 100644 --- a/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +++ b/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb @@ -1,3 +1,3 @@ module Bundler::Molinillo - VERSION = '0.2.3' + VERSION = '0.3.0' end diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb b/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb index 79a85e778f..e6324bab17 100644 --- a/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +++ b/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb @@ -86,5 +86,14 @@ module Bundler::Molinillo ] end end + + # Returns whether this dependency, which has no possible matching + # specifications, can safely be ignored. + # + # @param [Object] dependency + # @return [Boolean] whether this dependency can safely be skipped. + def allow_missing?(dependency) + false + end end end diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb b/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb index 46a47d8028..fc7fe86c7d 100644 --- a/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +++ b/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb @@ -93,7 +93,7 @@ module Bundler::Molinillo def start_resolution @started_at = Time.now - states.push(initial_state) + handle_missing_or_push_dependency_state(initial_state) debug { "Starting resolution (#{@started_at})" } resolver_ui.before_resolution @@ -116,7 +116,8 @@ module Bundler::Molinillo ResolutionState.new.members.each do |member| define_method member do |*args, &block| - state.send(member, *args, &block) + current_state = state || ResolutionState.empty + current_state.send(member, *args, &block) end end @@ -397,19 +398,33 @@ module Bundler::Molinillo # requirements # @param [Array] new_requirements # @return [void] - def push_state_for_requirements(new_requirements) - new_requirements = sort_dependencies(new_requirements.uniq, activated, conflicts) + def push_state_for_requirements(new_requirements, new_activated = activated.dup) + new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts) new_requirement = new_requirements.shift - states.push DependencyState.new( - new_requirement ? name_for(new_requirement) : '', - new_requirements, - activated.dup, - new_requirement, - new_requirement ? search_for(new_requirement) : [], - depth, - conflicts.dup + new_name = new_requirement ? name_for(new_requirement) : '' + possibilities = new_requirement ? search_for(new_requirement) : [] + handle_missing_or_push_dependency_state DependencyState.new( + new_name, new_requirements, new_activated, + new_requirement, possibilities, depth, conflicts.dup ) end + + # Pushes a new {DependencyState}. + # If the {#specification_provider} says to + # {SpecificationProvider#allow_missing?} that particular requirement, and + # there are no possibilities for that requirement, then `state` is not + # pushed, and the node in {#activated} is removed, and we continue + # resolving the remaining requirements. + # @param [DependencyState] state + # @return [void] + 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) + else + states.push state + end + end end end end diff --git a/lib/bundler/vendor/molinillo/lib/molinillo/state.rb b/lib/bundler/vendor/molinillo/lib/molinillo/state.rb index 8e394f8672..82744a6070 100644 --- a/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +++ b/lib/bundler/vendor/molinillo/lib/molinillo/state.rb @@ -17,6 +17,14 @@ module Bundler::Molinillo :conflicts ) + class ResolutionState + # Returns an empty resolution state + # @return [ResolutionState] an empty state + def self.empty + new(nil, [], DependencyGraph.new, nil, nil, 0, Set.new) + end + end + # A state that encapsulates a set of {#requirements} with an {Array} of # possibilities class DependencyState < ResolutionState |