diff options
author | Carlhuda <carlhuda@engineyard.com> | 2010-06-16 17:14:06 -0700 |
---|---|---|
committer | wycats <wycats@gmail.com> | 2010-06-29 14:44:50 -0700 |
commit | ee100997d6e788a57523147a1b0d8af9ab73ee37 (patch) | |
tree | 7c710f11d43eea90579936f40be7336833a19aff | |
parent | f1d7e4fe3c2cb392405ac20fece81a0d74a1971c (diff) | |
download | bundler-ee100997d6e788a57523147a1b0d8af9ab73ee37.tar.gz |
Refactor resolver error messages, less code and more consistency
-rw-r--r-- | lib/bundler/lazy_specification.rb | 4 | ||||
-rw-r--r-- | lib/bundler/resolver.rb | 66 | ||||
-rw-r--r-- | spec/install/gems/flex_spec.rb | 5 | ||||
-rw-r--r-- | spec/other/check_spec.rb | 5 |
4 files changed, 52 insertions, 28 deletions
diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb index 5ee26ec988..4015752cf6 100644 --- a/lib/bundler/lazy_specification.rb +++ b/lib/bundler/lazy_specification.rb @@ -52,6 +52,10 @@ module Bundler super || @specification.respond_to?(*args) end + def to_s + "#{name} (#{version})" + end + private def method_missing(method, *args, &blk) diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb index 5dc3d6a4ff..ef710911f6 100644 --- a/lib/bundler/resolver.rb +++ b/lib/bundler/resolver.rb @@ -87,6 +87,10 @@ module Bundler @specs[platform] end + def to_s + "#{name} (#{version})" + end + private def __dependencies @@ -377,49 +381,65 @@ module Bundler VersionConflict.new(errors.keys, error_message) end + # For a given conflicted requirement, print out what exactly went wrong + def gem_message(requirement) + m = "" + + # A requirement that is required by itself is actually in the Gemfile, and does + # not "depend on" itself + if requirement.required_by.first && requirement.required_by.first.name != requirement.name + m << " #{clean_req(requirement.required_by.first)} depends on\n" + m << " #{clean_req(requirement)}\n" + else + m << " #{clean_req(requirement)}\n" + end + m << "\n" + end + def error_message output = errors.inject("") do |o, (conflict, (origin, requirement))| + + # origin is the SpecSet of specs from the Gemfile that is conflicted with if origin - o << "Bundler could not find compatible versions for gem #{conflict.inspect}:\n" + o << %{Bundler could not find compatible versions for gem "#{origin.name}":\n} o << " In Gemfile:\n" - if requirement.required_by.first - o << " #{clean_req(requirement.required_by.first)} depends on\n" - o << " #{clean_req(requirement)}\n" - else - o << " #{clean_req(requirement)}\n" - end - o << "\n" + o << gem_message(requirement) + + # If the origin is a LockfileParser, it does not respond_to :required_by unless origin.respond_to?(:required_by) && required_by = origin.required_by.first o << " In snapshot (Gemfile.lock):\n" end - if origin.required_by.first && origin.required_by.first.name != origin.name - o << " #{clean_req(origin.required_by.first)} depends on\n" - o << " #{origin.name} (#{clean_req(origin.version)})\n" - else - o << " #{origin.name} (#{clean_req(origin.version)})\n" - end + o << gem_message(origin) + # origin is nil if the required gem and version cannot be found in any of + # the specified sources else - if @base[conflict].any? + # if the gem cannot be found because of a version conflict between lockfile and gemfile, + # print a useful error that suggests running `bundle update`, which may fix things + # + # @base is a SpecSet of the gems in the lockfile + # conflict is the name of the gem that could not be found + if locked = @base[conflict].first o << "Bundler could not find compatible versions for gem #{conflict.inspect}:\n" - locked = @base[conflict].first o << " In snapshot (Gemfile.lock):\n" - o << " #{conflict} (#{clean_req(locked.version)})\n\n" + o << " #{clean_req(locked)}\n\n" o << " In Gemfile:\n" + o << gem_message(requirement) + 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" + + # the rest of the time, the gem cannot be found because it does not exist in the known sources + else if requirement.required_by.first - o << " #{clean_req(requirement.required_by.first)}\n" - o << " #{clean_req(requirement)}\n" + o << "Could not find gem '#{clean_req(requirement)}', required by '#{clean_req(requirement.required_by.first)}', in any of the sources\n" else - o << " #{clean_req(requirement)}\n" + o << "Could not find gem '#{clean_req(requirement)} in any of the sources\n" end - o << "\nRunning `bundle update` will try to resolve the conflict between your Gemfile and snapshot.\n" - else - o << "Could not find the gem '#{clean_req(requirement)}', required by gem '#{clean_req(requirement.required_by.first)}'\n" end end diff --git a/spec/install/gems/flex_spec.rb b/spec/install/gems/flex_spec.rb index 75404f5749..07d60f19c0 100644 --- a/spec/install/gems/flex_spec.rb +++ b/spec/install/gems/flex_spec.rb @@ -199,10 +199,11 @@ describe "bundle flex_install" do rack (0.9.1) In Gemfile: - rack-obama (= 2.0) + rack-obama (= 2.0) depends on rack (= 1.2) - Running `bundle update` will try to resolve the conflict between your Gemfile and snapshot. + Running `bundle update` will rebuild your snapshot from scratch, using only + the gems in your Gemfile, which may resolve the conflict. E bundle :install diff --git a/spec/other/check_spec.rb b/spec/other/check_spec.rb index 5b6dd5160a..056af50ad6 100644 --- a/spec/other/check_spec.rb +++ b/spec/other/check_spec.rb @@ -30,9 +30,8 @@ describe "bundle check" do G bundle :check - puts out - out.should include(%{Could not find the gem 'not_here'}) - out.should include(%{required by gem 'missing_dep'}) + out.should include(%{Could not find gem 'not_here'}) + out.should include(%{required by 'missing_dep'}) end it "provides debug information when there is a resolving problem" do |