Split debrew up to faciliate test isolation
We want to be able to test the raise functionality without monkey-patching #raise on every object in the system, which is one of the side effects of loading debrew.rb.
This commit is contained in:
parent
46e49c4889
commit
a75dd6e8a8
@ -2,88 +2,12 @@ def can_use_readline?
|
|||||||
not ENV['HOMEBREW_NO_READLINE']
|
not ENV['HOMEBREW_NO_READLINE']
|
||||||
end
|
end
|
||||||
|
|
||||||
require 'irb' if can_use_readline?
|
require 'debrew/menu'
|
||||||
require 'continuation' if RUBY_VERSION.to_f >= 1.9
|
require 'debrew/raise_plus'
|
||||||
|
require 'debrew/irb' if can_use_readline?
|
||||||
|
|
||||||
class Menu
|
class Object
|
||||||
attr_accessor :prompt
|
include RaisePlus
|
||||||
attr_accessor :entries
|
|
||||||
|
|
||||||
def initialize
|
|
||||||
@entries = []
|
|
||||||
end
|
|
||||||
|
|
||||||
def choice(name, &action)
|
|
||||||
entries << { :name => name, :action => action }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def choose
|
|
||||||
menu = Menu.new
|
|
||||||
yield menu
|
|
||||||
|
|
||||||
choice = nil
|
|
||||||
while choice.nil?
|
|
||||||
menu.entries.each_with_index do |entry, i|
|
|
||||||
puts "#{i+1}. #{entry[:name]}"
|
|
||||||
end
|
|
||||||
print menu.prompt unless menu.prompt.nil?
|
|
||||||
reply = $stdin.gets.chomp
|
|
||||||
|
|
||||||
i = reply.to_i
|
|
||||||
if i > 0
|
|
||||||
choice = menu.entries[i-1]
|
|
||||||
else
|
|
||||||
possible = menu.entries.find_all {|e| e[:name].to_s.start_with? reply }
|
|
||||||
case possible.size
|
|
||||||
when 0 then puts "No such option"
|
|
||||||
when 1 then choice = possible.first
|
|
||||||
else puts "Multiple options match: #{possible.map{|e| e[:name]}.join(' ')}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
choice[:action].call
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
module IRB
|
|
||||||
@setup_done = false
|
|
||||||
|
|
||||||
def IRB.start_within(binding)
|
|
||||||
unless @setup_done
|
|
||||||
# make IRB ignore our command line arguments
|
|
||||||
saved_args = ARGV.shift(ARGV.size)
|
|
||||||
IRB.setup(nil)
|
|
||||||
ARGV.concat(saved_args)
|
|
||||||
@setup_done = true
|
|
||||||
end
|
|
||||||
|
|
||||||
workspace = WorkSpace.new(binding)
|
|
||||||
irb = Irb.new(workspace)
|
|
||||||
|
|
||||||
@CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
|
|
||||||
@CONF[:MAIN_CONTEXT] = irb.context
|
|
||||||
|
|
||||||
trap("SIGINT") do
|
|
||||||
irb.signal_handle
|
|
||||||
end
|
|
||||||
|
|
||||||
begin
|
|
||||||
catch(:IRB_EXIT) do
|
|
||||||
irb.eval_input
|
|
||||||
end
|
|
||||||
ensure
|
|
||||||
irb_at_exit
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end if can_use_readline?
|
|
||||||
|
|
||||||
class Exception
|
|
||||||
attr_accessor :continuation
|
|
||||||
|
|
||||||
def restart(&block)
|
|
||||||
continuation.call block
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_debugger?
|
def has_debugger?
|
||||||
@ -131,42 +55,3 @@ def debrew(exception, formula=nil)
|
|||||||
end
|
end
|
||||||
end while again
|
end while again
|
||||||
end
|
end
|
||||||
|
|
||||||
module RaisePlus
|
|
||||||
alias :original_raise :raise
|
|
||||||
|
|
||||||
def raise(*args)
|
|
||||||
exception = case
|
|
||||||
when args.size == 0
|
|
||||||
$!.nil? ? RuntimeError.exception : $!
|
|
||||||
when args.size == 1 && args[0].is_a?(String)
|
|
||||||
RuntimeError.exception(args[0])
|
|
||||||
when args.size == 2 && args[0].is_a?(Exception)
|
|
||||||
args[0].exception(args[1])
|
|
||||||
when args[0].is_a?(Class) && args[0].ancestors.include?(Exception)
|
|
||||||
args[0].exception(args[1])
|
|
||||||
else
|
|
||||||
args[0]
|
|
||||||
end
|
|
||||||
|
|
||||||
# passing something other than a String or Exception is illegal, but if someone does it anyway,
|
|
||||||
# that object won't have backtrace or continuation methods. in that case, let's pass it on to
|
|
||||||
# the original raise, which will reject it
|
|
||||||
return super exception unless exception.is_a?(Exception)
|
|
||||||
|
|
||||||
# keep original backtrace if reraising
|
|
||||||
exception.set_backtrace(args.size >= 3 ? args[2] : caller) if exception.backtrace.nil?
|
|
||||||
|
|
||||||
blk = callcc do |cc|
|
|
||||||
exception.continuation = cc
|
|
||||||
super exception
|
|
||||||
end
|
|
||||||
blk.call unless blk.nil?
|
|
||||||
end
|
|
||||||
|
|
||||||
alias :fail :raise
|
|
||||||
end
|
|
||||||
|
|
||||||
class Object
|
|
||||||
include RaisePlus
|
|
||||||
end
|
|
||||||
|
7
Library/Homebrew/debrew/exception.rb
Normal file
7
Library/Homebrew/debrew/exception.rb
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
class Exception
|
||||||
|
attr_accessor :continuation
|
||||||
|
|
||||||
|
def restart(&block)
|
||||||
|
continuation.call block
|
||||||
|
end
|
||||||
|
end
|
33
Library/Homebrew/debrew/irb.rb
Normal file
33
Library/Homebrew/debrew/irb.rb
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
require 'irb'
|
||||||
|
|
||||||
|
module IRB
|
||||||
|
@setup_done = false
|
||||||
|
|
||||||
|
def IRB.start_within(binding)
|
||||||
|
unless @setup_done
|
||||||
|
# make IRB ignore our command line arguments
|
||||||
|
saved_args = ARGV.shift(ARGV.size)
|
||||||
|
IRB.setup(nil)
|
||||||
|
ARGV.concat(saved_args)
|
||||||
|
@setup_done = true
|
||||||
|
end
|
||||||
|
|
||||||
|
workspace = WorkSpace.new(binding)
|
||||||
|
irb = Irb.new(workspace)
|
||||||
|
|
||||||
|
@CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
|
||||||
|
@CONF[:MAIN_CONTEXT] = irb.context
|
||||||
|
|
||||||
|
trap("SIGINT") do
|
||||||
|
irb.signal_handle
|
||||||
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
catch(:IRB_EXIT) do
|
||||||
|
irb.eval_input
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
irb_at_exit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
39
Library/Homebrew/debrew/menu.rb
Normal file
39
Library/Homebrew/debrew/menu.rb
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
class Menu
|
||||||
|
attr_accessor :prompt
|
||||||
|
attr_accessor :entries
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
@entries = []
|
||||||
|
end
|
||||||
|
|
||||||
|
def choice(name, &action)
|
||||||
|
entries << { :name => name, :action => action }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def choose
|
||||||
|
menu = Menu.new
|
||||||
|
yield menu
|
||||||
|
|
||||||
|
choice = nil
|
||||||
|
while choice.nil?
|
||||||
|
menu.entries.each_with_index do |entry, i|
|
||||||
|
puts "#{i+1}. #{entry[:name]}"
|
||||||
|
end
|
||||||
|
print menu.prompt unless menu.prompt.nil?
|
||||||
|
reply = $stdin.gets.chomp
|
||||||
|
|
||||||
|
i = reply.to_i
|
||||||
|
if i > 0
|
||||||
|
choice = menu.entries[i-1]
|
||||||
|
else
|
||||||
|
possible = menu.entries.find_all {|e| e[:name].to_s.start_with? reply }
|
||||||
|
case possible.size
|
||||||
|
when 0 then puts "No such option"
|
||||||
|
when 1 then choice = possible.first
|
||||||
|
else puts "Multiple options match: #{possible.map{|e| e[:name]}.join(' ')}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
choice[:action].call
|
||||||
|
end
|
44
Library/Homebrew/debrew/raise_plus.rb
Normal file
44
Library/Homebrew/debrew/raise_plus.rb
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
require 'continuation' if RUBY_VERSION.to_f >= 1.9
|
||||||
|
|
||||||
|
class Exception
|
||||||
|
attr_accessor :continuation
|
||||||
|
|
||||||
|
def restart(&block)
|
||||||
|
continuation.call block
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module RaisePlus
|
||||||
|
alias :original_raise :raise
|
||||||
|
|
||||||
|
def raise(*args)
|
||||||
|
exception = case
|
||||||
|
when args.size == 0
|
||||||
|
$!.nil? ? RuntimeError.exception : $!
|
||||||
|
when args.size == 1 && args[0].is_a?(String)
|
||||||
|
RuntimeError.exception(args[0])
|
||||||
|
when args.size == 2 && args[0].is_a?(Exception)
|
||||||
|
args[0].exception(args[1])
|
||||||
|
when args[0].is_a?(Class) && args[0].ancestors.include?(Exception)
|
||||||
|
args[0].exception(args[1])
|
||||||
|
else
|
||||||
|
args[0]
|
||||||
|
end
|
||||||
|
|
||||||
|
# passing something other than a String or Exception is illegal, but if someone does it anyway,
|
||||||
|
# that object won't have backtrace or continuation methods. in that case, let's pass it on to
|
||||||
|
# the original raise, which will reject it
|
||||||
|
return super exception unless exception.is_a?(Exception)
|
||||||
|
|
||||||
|
# keep original backtrace if reraising
|
||||||
|
exception.set_backtrace(args.size >= 3 ? args[2] : caller) if exception.backtrace.nil?
|
||||||
|
|
||||||
|
blk = callcc do |cc|
|
||||||
|
exception.continuation = cc
|
||||||
|
super exception
|
||||||
|
end
|
||||||
|
blk.call unless blk.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
alias :fail :raise
|
||||||
|
end
|
Loading…
x
Reference in New Issue
Block a user