summaryrefslogtreecommitdiff
path: root/lib/bundler/resolver.rb
diff options
context:
space:
mode:
authorSamuel E. Giddins <segiddins@segiddins.me>2014-11-16 20:26:48 -0800
committerSamuel E. Giddins <segiddins@segiddins.me>2014-11-24 11:03:49 -0800
commit1b652eda6f308f57518bdb58d4c0d476f2a78939 (patch)
tree8145fc241f3894910e0c1719e7e6016afb9dbd68 /lib/bundler/resolver.rb
parentb2e0d9707b53a7d799a1dd089ff7e479abacb5fb (diff)
downloadbundler-1b652eda6f308f57518bdb58d4c0d476f2a78939.tar.gz
[Resolver] Fix all remaining molinillo spec failures
Diffstat (limited to 'lib/bundler/resolver.rb')
-rw-r--r--lib/bundler/resolver.rb99
1 files changed, 91 insertions, 8 deletions
diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb
index 2b9cfde810..99aa8e01d8 100644
--- a/lib/bundler/resolver.rb
+++ b/lib/bundler/resolver.rb
@@ -11,6 +11,63 @@ module Bundler
require 'bundler/vendored_molinillo'
+ class Molinillo::VersionConflict
+ def clean_req(req)
+ if req.to_s.include?(">= 0")
+ req.to_s.gsub(/ \(.*?\)$/, '')
+ else
+ req.to_s.gsub(/\, (runtime|development)\)$/, ')')
+ end
+ end
+
+ def message
+ conflicts.values.flatten.reduce('') do |o, conflict|
+ o << %(Bundler could not find compatible versions for gem "#{conflict.requirement.name}":\n)
+ if conflict.locked_requirement
+ o << %( In snapshot (Gemfile.lock):\n)
+ o << %( #{clean_req conflict.locked_requirement}\n)
+ o << %(\n)
+ end
+ o << %( In Gemfile:\n)
+ o << conflict.requirement_trees.map do |tree|
+ t = ''
+ depth = 2
+ tree.each do |req|
+ t << ' ' * depth << %(#{clean_req req})
+ t << %( depends on) unless tree[-1] == req
+ t << %(\n)
+ depth += 1
+ end
+ t
+ end.join("\n")
+
+ if conflict.requirement.name == 'bundler'
+ o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
+ other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new Bundler::VERSION)
+ end
+
+ if conflict.requirement.name == "bundler" && other_bundler_required
+ o << "\n"
+ o << "This Gemfile requires a different version of Bundler.\n"
+ o << "Perhaps you need to update Bundler by running `gem install bundler`?"
+ end
+ if conflict.locked_requirement
+ o << "\n"
+ o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
+ o << %(the gems in your Gemfile, which may resolve the conflict.\n)
+ elsif !conflict.existing
+ if conflict.requirement_trees.first.size > 1
+ o << "Could not find gem '#{clean_req(conflict.requirement)}', which is required by "
+ o << "gem '#{clean_req(conflict.requirement_trees.first.last)}', in any of the sources."
+ else
+ o << "Could not find gem '#{clean_req(conflict.requirement)} in any of the sources\n"
+ end
+ end
+ o
+ end
+ end
+ end
+
ALL = Bundler::Dependency::PLATFORM_MAP.values.uniq.freeze
class SpecGroup < Array
@@ -120,15 +177,10 @@ module Bundler
# <GemBundle>,nil:: If the list of dependencies can be resolved, a
# collection of gemspecs is returned. Otherwise, nil is returned.
def self.resolve(requirements, index, source_requirements = {}, base = [])
- Bundler.ui.info "Resolving dependencies...", false
base = SpecSet.new(base) unless base.is_a?(SpecSet)
resolver = new(index, source_requirements, base)
result = resolver.start(requirements)
- Bundler.ui.info "" # new line now that dots are done
SpecSet.new(result)
- rescue
- Bundler.ui.info "" # new line before the error
- raise
end
@@ -158,11 +210,20 @@ module Bundler
include Molinillo::UI
+ def debug?
+ ENV['DEBUG_RESOLVER'] || ENV['DEBUG_RESOLVER_TREE']
+ end
+
def before_resolution
+ Bundler.ui.info 'Resolving dependencies...', false
end
+
def after_resolution
+ Bundler.ui.info ''
end
+
def indicate_progress
+ Bundler.ui.info '.', false
end
private
@@ -178,8 +239,6 @@ module Bundler
dependency = dependency.dep unless dependency.is_a? Gem::Dependency
search = @search_for[dependency.hash] ||= begin
index = @source_requirements[dependency.name] || @index
- # puts dependency
- # puts index.search(dependency, nil)
results = index.search(dependency, @base[dependency.name])
if vertex = @base_dg.vertex_named(dependency.name)
locked_requirement = vertex.payload.requirement
@@ -233,8 +292,32 @@ module Bundler
def verify_gemfile_dependencies_are_found!(requirements)
requirements.each do |requirement|
+ next if requirement.name == 'bundler'
if search_for(requirement).empty?
- raise GemNotFound, "Could not find gem '#{requirement}'"
+ if base = @base[requirement.name] and !base.empty?
+ version = base.first.version
+ message = "You have requested:\n" \
+ " #{requirement.name} #{requirement.requirement}\n\n" \
+ "The bundle currently has #{requirement.name} locked at #{version}.\n" \
+ "Try running `bundle update #{requirement.name}`"
+ elsif requirement.source
+ name = requirement.name
+ versions = @source_requirements[name][name].map { |s| s.version }
+ message = "Could not find gem '#{requirement}' in #{requirement.source}.\n"
+ if versions.any?
+ message << "Source contains '#{name}' at: #{versions.join(', ')}"
+ else
+ message << "Source does not contain any versions of '#{requirement}'"
+ end
+ else
+ message = "Could not find gem '#{requirement}' "
+ if @index.source_types.include?(Bundler::Source::Rubygems)
+ message << "in any of the gem sources listed in your Gemfile."
+ else
+ message << "in the gems available on this machine."
+ end
+ end
+ raise GemNotFound, message
end
end
end