summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Giddins <segiddins@segiddins.me>2018-08-01 00:26:20 -0700
committerSamuel Giddins <segiddins@segiddins.me>2018-08-06 23:08:02 -0700
commit32222b5e892fc548c59890bd45919fee1959603f (patch)
treeb529ef1ccca6f0e3dfb3f2747ce326415991a22e
parent017cc4db7fead17ffb3470d958fc344dae8fad82 (diff)
downloadbundler-32222b5e892fc548c59890bd45919fee1959603f.tar.gz
Make version conflict messages better
-rw-r--r--lib/bundler/resolver.rb40
-rw-r--r--spec/install/gems/resolving_spec.rb5
2 files changed, 34 insertions, 11 deletions
diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb
index 8872b861be..13fe436cb1 100644
--- a/lib/bundler/resolver.rb
+++ b/lib/bundler/resolver.rb
@@ -302,10 +302,23 @@ module Bundler
end
def version_conflict_message(e)
+ # only show essential conflicts, if possible
+ conflicts = e.conflicts.dup
+ conflicts.delete_if do |_name, conflict|
+ deps = conflict.requirement_trees.map(&:last).flatten(1)
+ !Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
+ end
+ e.conflicts.replace(conflicts) unless conflicts.empty?
+
+ solver_name = "Bundler"
+ possibility_type = "gem"
e.message_with_trees(
- :solver_name => "Bundler",
- :possibility_type => "gem",
+ :solver_name => solver_name,
+ :possibility_type => possibility_type,
:reduce_trees => lambda do |trees|
+ # called first, because we want to reduce the amount of work required to find maximal empty sets
+ trees.uniq! {|t| t.flatten.map {|dep| [dep.name, dep.requirement] } }
+
# bail out if tree size is too big for Array#combination to make any sense
return trees if trees.size > 15
maximal = 1.upto(trees.size).map do |size|
@@ -313,12 +326,10 @@ module Bundler
end.flatten(1).select do |deps|
Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
end.min_by(&:size)
- trees.reject! {|t| !maximal.include?(t.last) } if maximal
- trees = trees.sort_by {|t| t.flatten.map(&:to_s) }
- trees.uniq! {|t| t.flatten.map {|dep| [dep.name, dep.requirement] } }
+ trees.reject! {|t| !maximal.include?(t.last) } if maximal
- trees.sort_by {|t| t.reverse.map(&:name) }
+ trees.sort_by {|t| [t.flatten.map(&:to_s), t.reverse.map(&:name)] }
end,
:printable_requirement => lambda {|req| SharedHelpers.pretty_dependency(req) },
:additional_message_for_conflict => lambda do |o, name, conflict|
@@ -351,7 +362,11 @@ module Bundler
[]
end.compact.map(&:to_s).uniq.sort
- o << "Could not find gem '#{SharedHelpers.pretty_dependency(conflict.requirement)}'"
+ metadata_requirement = name.end_with?("\0")
+
+ o << "Could not find gem '" unless metadata_requirement
+ o << SharedHelpers.pretty_dependency(conflict.requirement)
+ o << "'" unless metadata_requirement
if conflict.requirement_trees.first.size > 1
o << ", which is required by "
o << "gem '#{SharedHelpers.pretty_dependency(conflict.requirement_trees.first[-2])}',"
@@ -360,12 +375,21 @@ module Bundler
o << if relevant_sources.empty?
"in any of the sources.\n"
+ elsif metadata_requirement
+ "is not available in #{relevant_sources.join(" or ")}"
else
"in any of the relevant sources:\n #{relevant_sources * "\n "}\n"
end
end
end,
- :version_for_spec => lambda {|spec| spec.version }
+ :version_for_spec => lambda {|spec| spec.version },
+ :incompatible_version_message_for_conflict => lambda do |name, _conflict|
+ if name.end_with?("\0")
+ %(#{solver_name} found conflicting requirements for the #{name} version:)
+ else
+ %(#{solver_name} could not find compatible versions for #{possibility_type} "#{name}":)
+ end
+ end
)
end
diff --git a/spec/install/gems/resolving_spec.rb b/spec/install/gems/resolving_spec.rb
index e58f32836c..844653d494 100644
--- a/spec/install/gems/resolving_spec.rb
+++ b/spec/install/gems/resolving_spec.rb
@@ -142,15 +142,14 @@ RSpec.describe "bundle install with install-time dependencies" do
expect(out).to_not include("Gem::InstallError: require_ruby requires Ruby version > 9000")
nice_error = strip_whitespace(<<-E).strip
- Bundler could not find compatible versions for gem "ruby\0":
+ Bundler found conflicting requirements for the ruby\0 version:
In Gemfile:
ruby\0 (#{error_message_requirement})
require_ruby was resolved to 1.0, which depends on
ruby\0 (> 9000)
- Could not find gem 'ruby\0 (> 9000)', which is required by gem 'require_ruby', in any of the relevant sources:
- the local ruby installation
+ ruby\0 (> 9000), which is required by gem 'require_ruby', is not available in the local ruby installation
E
expect(last_command.bundler_err).to end_with(nice_error)
end