class Bundler::Resolver
def resolve_requirement(spec, requirement, reqs, activated)
def resolve_requirement(spec, requirement, reqs, activated) # We are going to try activating the spec. We need to keep track of stack of # requirements that got us to the point of activating this gem. spec.required_by.replace requirement.required_by spec.required_by << requirement activated[spec.name] = spec debug { " Activating: #{spec.name} (#{spec.version})" } debug { spec.required_by.map { |d| " * #{d.name} (#{d.version_requirements})" }.join("\n") } # Now, we have to loop through all child dependencies and add them to our # array of requirements. debug { " Dependencies"} spec.dependencies.each do |dep| next if dep.type == :development debug { " * #{dep.name} (#{dep.version_requirements})" } dep.required_by.replace(requirement.required_by) dep.required_by << requirement reqs << dep end # We create a savepoint and mark it by the name of the requirement that caused # the gem to be activated. If the activated gem ever conflicts, we are able to # jump back to this point and try another version of the gem. length = @stack.length @stack << requirement.name retval = catch(requirement.name) do resolve(reqs, activated) end # Since we're doing a lot of throw / catches. A push does not necessarily match # up to a pop. So, we simply slice the stack back to what it was before the catch # block. @stack.slice!(length..-1) retval end