summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/bundler/installer/parallel_installer.rb16
-rw-r--r--lib/bundler/spec_set.rb7
-rw-r--r--spec/install/failure_spec.rb33
-rw-r--r--spec/install/gemfile/git_spec.rb7
4 files changed, 61 insertions, 2 deletions
diff --git a/lib/bundler/installer/parallel_installer.rb b/lib/bundler/installer/parallel_installer.rb
index b1a997f3f2..97c124e015 100644
--- a/lib/bundler/installer/parallel_installer.rb
+++ b/lib/bundler/installer/parallel_installer.rb
@@ -90,6 +90,7 @@ module Bundler
@standalone = standalone
@force = force
@specs = all_specs.map {|s| SpecInstallation.new(s) }
+ @spec_set = all_specs
end
def call
@@ -116,7 +117,7 @@ module Bundler
spec_install.post_install_message = message
elsif !success
spec_install.state = :failed
- spec_install.error = message
+ spec_install.error = "#{message}\n\n#{require_tree_for_spec(spec_install.spec)}"
end
spec_install
}
@@ -166,6 +167,19 @@ module Bundler
Bundler.ui.warn(warning.join("\n"))
end
+ def require_tree_for_spec(spec)
+ tree = @spec_set.what_required(spec)
+ t = String.new("In #{File.basename(SharedHelpers.default_gemfile)}:\n")
+ tree.each_with_index do |s, depth|
+ t << " " * depth.succ << s.name
+ unless tree.last == s
+ t << %( was resolved to #{s.version}, which depends on)
+ end
+ t << %(\n)
+ end
+ t
+ end
+
# Keys in the remains hash represent uninstalled gems specs.
# We enqueue all gem specs that do not have any dependencies.
# Later we call this lambda again to install specs that depended on
diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb
index 19b9cddc3e..2dbb2faa77 100644
--- a/lib/bundler/spec_set.rb
+++ b/lib/bundler/spec_set.rb
@@ -118,6 +118,13 @@ module Bundler
@specs.detect {|spec| spec.name == name && spec.match_platform(platform) }
end
+ def what_required(spec)
+ unless req = find {|s| s.dependencies.any? {|d| d.runtime? && d.name == spec.name } }
+ return [spec]
+ end
+ what_required(req) << spec
+ end
+
private
def sorted
diff --git a/spec/install/failure_spec.rb b/spec/install/failure_spec.rb
new file mode 100644
index 0000000000..738b2cf1bd
--- /dev/null
+++ b/spec/install/failure_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+require "spec_helper"
+
+RSpec.describe "bundle install" do
+ context "installing a gem fails" do
+ it "prints out why that gem was being installed" do
+ build_repo2 do
+ build_gem "activesupport", "2.3.2" do |s|
+ s.extensions << "Rakefile"
+ s.write "Rakefile", <<-RUBY
+ task :default do
+ abort "make installing activesupport-2.3.2 fail"
+ end
+ RUBY
+ end
+ end
+
+ install_gemfile <<-G
+ source "file:#{gem_repo2}"
+ gem "rails"
+ G
+ expect(out).to end_with(<<-M.strip)
+An error occurred while installing activesupport (2.3.2), and Bundler cannot continue.
+Make sure that `gem install activesupport -v '2.3.2'` succeeds before bundling.
+
+In Gemfile:
+ rails was resolved to 2.3.2, which depends on
+ actionmailer was resolved to 2.3.2, which depends on
+ activesupport
+ M
+ end
+ end
+end
diff --git a/spec/install/gemfile/git_spec.rb b/spec/install/gemfile/git_spec.rb
index ce639ee89f..d2d46279aa 100644
--- a/spec/install/gemfile/git_spec.rb
+++ b/spec/install/gemfile/git_spec.rb
@@ -1085,7 +1085,12 @@ RSpec.describe "bundle install with git sources" do
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
- expect(out).to include("An error occurred while installing foo (1.0)")
+ expect(out).to end_with(<<-M.strip)
+An error occurred while installing foo (1.0), and Bundler cannot continue.
+
+In Gemfile:
+ foo
+ M
expect(out).not_to include("gem install foo")
end