summaryrefslogtreecommitdiff
path: root/lib/bundler/installer
diff options
context:
space:
mode:
authorSamuel Giddins <segiddins@segiddins.me>2016-08-02 17:50:19 -0500
committerSamuel Giddins <segiddins@segiddins.me>2016-08-04 18:09:57 -0500
commit240ea12d8e053440f41b0b0352bbbd6c3739393d (patch)
tree3fddc9fbab1edb8065b84da7b1d092a93d61a414 /lib/bundler/installer
parentc5e902f912abc505ccc34870747bd7396844723b (diff)
downloadbundler-240ea12d8e053440f41b0b0352bbbd6c3739393d.tar.gz
[Install] Print errors at the end of installation instead of inline
Diffstat (limited to 'lib/bundler/installer')
-rw-r--r--lib/bundler/installer/gem_installer.rb28
-rw-r--r--lib/bundler/installer/parallel_installer.rb34
2 files changed, 39 insertions, 23 deletions
diff --git a/lib/bundler/installer/gem_installer.rb b/lib/bundler/installer/gem_installer.rb
index a91990d5f5..c8c261de6f 100644
--- a/lib/bundler/installer/gem_installer.rb
+++ b/lib/bundler/installer/gem_installer.rb
@@ -15,16 +15,24 @@ module Bundler
post_install_message = spec_settings ? install_with_settings : install
Bundler.ui.debug "#{worker}: #{spec.name} (#{spec.version}) from #{spec.loaded_from}"
generate_executable_stubs
- post_install_message
-
+ return true, post_install_message
+ rescue Bundler::InstallHookError, Bundler::SecurityError
+ raise
rescue Errno::ENOSPC
- raise Bundler::InstallError, out_of_space_message
+ return false, out_of_space_message
rescue => e
- handle_exception(e)
+ return false, specific_failure_message(e)
end
private
+ def specific_failure_message(e)
+ message = "#{e.class}: #{e.message}\n"
+ message += " " + e.backtrace.join("\n ") + "\n\n" if Bundler.ui.debug?
+ message = message.lines.first + Bundler.ui.add_color(message.lines[1..-1].join, :clear)
+ message + Bundler.ui.add_color(failure_message, :red)
+ end
+
def failure_message
return install_error_message if spec.source.options["git"]
"#{install_error_message}\n#{gem_install_message}"
@@ -38,16 +46,6 @@ module Bundler
"Make sure that `gem install #{spec.name} -v '#{spec.version}'` succeeds before bundling."
end
- def handle_exception(e)
- # Die if install hook failed or gem signature is bad.
- raise e if e.is_a?(Bundler::InstallHookError) || e.is_a?(Bundler::SecurityError)
- # other failure, likely a native extension build failure
- Bundler.ui.info ""
- Bundler.ui.warn "#{e.class}: #{e.message}"
- Bundler.ui.debug e.backtrace.join("\n")
- raise Bundler::InstallError, failure_message
- end
-
def spec_settings
# Fetch the build settings, if there are any
Bundler.settings["build.#{spec.name}"]
@@ -63,7 +61,7 @@ module Bundler
end
def out_of_space_message
- "Your disk is out of space. Free some space to be able to install your bundle."
+ "#{install_error_message}\nYour disk is out of space. Free some space to be able to install your bundle."
end
def generate_executable_stubs
diff --git a/lib/bundler/installer/parallel_installer.rb b/lib/bundler/installer/parallel_installer.rb
index d3ae86d174..ecc355ef48 100644
--- a/lib/bundler/installer/parallel_installer.rb
+++ b/lib/bundler/installer/parallel_installer.rb
@@ -5,12 +5,13 @@ require "bundler/installer/gem_installer"
module Bundler
class ParallelInstaller
class SpecInstallation
- attr_accessor :spec, :name, :post_install_message, :state
+ attr_accessor :spec, :name, :post_install_message, :state, :error
def initialize(spec)
@spec = spec
@name = spec.name
@state = :none
@post_install_message = ""
+ @error = nil
end
def installed?
@@ -21,9 +22,17 @@ module Bundler
state == :enqueued
end
+ def failed?
+ state == :failed
+ end
+
+ def installation_attempted?
+ installed? || failed?
+ end
+
# Only true when spec in neither installed nor already enqueued
def ready_to_enqueue?
- !installed? && !enqueued?
+ !enqueued? && !installation_attempted?
end
def has_post_install_message?
@@ -80,17 +89,24 @@ module Bundler
def call
enqueue_specs
- process_specs until @specs.all?(&:installed?)
+ process_specs until @specs.all?(&:installed?) || @specs.any?(&:failed?)
+ raise Bundler::InstallError, @specs.select(&:failed?).map(&:error).map(&:to_s).join("\n\n")
ensure
worker_pool && worker_pool.stop
end
def worker_pool
@worker_pool ||= Bundler::Worker.new @size, "Parallel Installer", lambda { |spec_install, worker_num|
- message = Bundler::GemInstaller.new(
+ gem_installer = Bundler::GemInstaller.new(
spec_install.spec, @installer, @standalone, worker_num, @force
- ).install_from_spec
- spec_install.post_install_message = message unless message.nil?
+ )
+ success, message = gem_installer.install_from_spec
+ if success && !message.nil?
+ spec_install.post_install_message = message
+ elsif !success
+ spec_install.state = :failed
+ spec_install.error = message
+ end
spec_install
}
end
@@ -102,8 +118,10 @@ module Bundler
# dequeue.
def process_specs
spec = worker_pool.deq
- spec.state = :installed
- collect_post_install_message spec if spec.has_post_install_message?
+ unless spec.failed?
+ spec.state = :installed
+ collect_post_install_message spec if spec.has_post_install_message?
+ end
enqueue_specs
end