Much better CTRL-C handling

Let's not show weird error messages when user interrupts during various stages of brew initialization.

Tested by doing `for x in $(brew search); do brew install $x; done` and pressing CTRL-C at random short intervals.
This commit is contained in:
Max Howell 2012-08-22 15:50:27 -04:00
parent fb8c7e0aaf
commit 20ce16a3ff
4 changed files with 53 additions and 42 deletions

View File

@ -1,18 +1,20 @@
#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby #!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -W0
# This script is called by formula_installer as a separate instance. # This script is called by formula_installer as a separate instance.
# Rationale: Formula can use __END__, Formula can change ENV # Rationale: Formula can use __END__, Formula can change ENV
# Thrown exceptions are propogated back to the parent process over a pipe # Thrown exceptions are propogated back to the parent process over a pipe
require 'global' STD_TRAP = trap("INT") { exit! 130 } # no backtrace thanks
at_exit do at_exit do
# the whole of everything must be run in at_exit because the formula has to # the whole of everything must be run in at_exit because the formula has to
# be the run script as __END__ must work for *that* formula. # be the run script as __END__ must work for *that* formula.
main
end
error_pipe = nil require 'global'
begin def main
# The main Homebrew process expects to eventually see EOF on the error # The main Homebrew process expects to eventually see EOF on the error
# pipe in FormulaInstaller#build. However, if any child process fails to # pipe in FormulaInstaller#build. However, if any child process fails to
# terminate (i.e, fails to close the descriptor), this won't happen, and # terminate (i.e, fails to close the descriptor), this won't happen, and
@ -27,6 +29,8 @@ at_exit do
raise $! if $! # an exception was already thrown when parsing the formula raise $! if $! # an exception was already thrown when parsing the formula
trap("INT", STD_TRAP) # restore default CTRL-C handler
require 'hardware' require 'hardware'
require 'keg' require 'keg'
@ -47,7 +51,6 @@ at_exit do
exit! 2 exit! 2
end end
end end
end
def install f def install f
# TODO replace with Formula DSL # TODO replace with Formula DSL

View File

@ -238,6 +238,7 @@ class FormulaInstaller
Process.wait Process.wait
data = read.read data = read.read
raise Marshal.load(data) unless data.nil? or data.empty? raise Marshal.load(data) unless data.nil? or data.empty?
raise Interrupt if $?.exitstatus == 130
raise "Suspicious installation failure" unless $?.success? raise "Suspicious installation failure" unless $?.success?
end end
@ -266,15 +267,18 @@ class FormulaInstaller
end end
keg = Keg.new(f.prefix) keg = Keg.new(f.prefix)
begin
keg.link keg.link
rescue Exception => e rescue Exception => e
onoe "The `brew link` step did not complete successfully." onoe "The `brew link` step did not complete successfully"
puts "The formula built, but is not symlinked into #{HOMEBREW_PREFIX}." puts "The formula built, but is not symlinked into #{HOMEBREW_PREFIX}"
puts "You can try again using `brew link #{f.name}`." puts "You can try again using `brew link #{f.name}'"
keg.unlink
ohai e, e.backtrace if ARGV.debug? ohai e, e.backtrace if ARGV.debug?
@show_summary_heading = true @show_summary_heading = true
ignore_interrupts{ keg.unlink }
raise unless e.kind_of? RuntimeError
end
end end
def fix_install_names def fix_install_names

View File

@ -217,7 +217,7 @@ def inreplace path, before=nil, after=nil
end end
def ignore_interrupts def ignore_interrupts
std_trap = trap("INT") {} std_trap = trap("INT") { puts "One sec, just cleaning up" }
yield yield
ensure ensure
trap("INT", std_trap) trap("INT", std_trap)

View File

@ -1,6 +1,8 @@
#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -W0 #!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -W0
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
std_trap = trap("INT") { exit! 130 } # no backtrace thanks
HOMEBREW_BREW_FILE = ENV['HOMEBREW_BREW_FILE'] = File.expand_path(__FILE__) HOMEBREW_BREW_FILE = ENV['HOMEBREW_BREW_FILE'] = File.expand_path(__FILE__)
require 'pathname' require 'pathname'
@ -49,6 +51,8 @@ rescue LoadError => e
end end
begin begin
trap("INT", std_trap) # restore default CTRL-C handler
aliases = {'ls' => :list, aliases = {'ls' => :list,
'homepage' => :home, 'homepage' => :home,
'-S' => :search, '-S' => :search,