diff options
| author | Jack Nagel | 2013-02-06 18:46:36 -0600 |
|---|---|---|
| committer | Jack Nagel | 2013-02-06 19:04:43 -0600 |
| commit | a75dd6e8a8308e3e83d8285c4aa6ff9b3d149cc2 (patch) | |
| tree | ab71473cafae113983feb70094e7de5e32eb77bd /Library/Homebrew/debrew | |
| parent | 46e49c4889cd4948fb18cefb075dd65b7800cf5c (diff) | |
| download | brew-a75dd6e8a8308e3e83d8285c4aa6ff9b3d149cc2.tar.bz2 | |
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.
Diffstat (limited to 'Library/Homebrew/debrew')
| -rw-r--r-- | Library/Homebrew/debrew/exception.rb | 7 | ||||
| -rw-r--r-- | Library/Homebrew/debrew/irb.rb | 33 | ||||
| -rw-r--r-- | Library/Homebrew/debrew/menu.rb | 39 | ||||
| -rw-r--r-- | Library/Homebrew/debrew/raise_plus.rb | 44 |
4 files changed, 123 insertions, 0 deletions
diff --git a/Library/Homebrew/debrew/exception.rb b/Library/Homebrew/debrew/exception.rb new file mode 100644 index 000000000..da8e56dae --- /dev/null +++ b/Library/Homebrew/debrew/exception.rb @@ -0,0 +1,7 @@ +class Exception + attr_accessor :continuation + + def restart(&block) + continuation.call block + end +end diff --git a/Library/Homebrew/debrew/irb.rb b/Library/Homebrew/debrew/irb.rb new file mode 100644 index 000000000..c81e3cf4b --- /dev/null +++ b/Library/Homebrew/debrew/irb.rb @@ -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 diff --git a/Library/Homebrew/debrew/menu.rb b/Library/Homebrew/debrew/menu.rb new file mode 100644 index 000000000..c59c500b8 --- /dev/null +++ b/Library/Homebrew/debrew/menu.rb @@ -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 diff --git a/Library/Homebrew/debrew/raise_plus.rb b/Library/Homebrew/debrew/raise_plus.rb new file mode 100644 index 000000000..74f59aa46 --- /dev/null +++ b/Library/Homebrew/debrew/raise_plus.rb @@ -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 |
