| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  | require "mutex_m" | 
					
						
							| 
									
										
										
										
											2015-01-01 01:21:59 -05:00
										 |  |  | require "debrew/irb" | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | module Debrew | 
					
						
							|  |  |  |   extend Mutex_m | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Ignorable = Module.new | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   module Raise | 
					
						
							|  |  |  |     def raise(*) | 
					
						
							|  |  |  |       super | 
					
						
							|  |  |  |     rescue Exception => e | 
					
						
							|  |  |  |       e.extend(Ignorable) | 
					
						
							|  |  |  |       super(e) unless Debrew.debug(e) == :ignore | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-23 18:13:48 +02:00
										 |  |  |     alias fail raise | 
					
						
							| 
									
										
										
										
											2013-02-07 18:58:41 -06:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |   module Formula | 
					
						
							| 
									
										
										
										
											2014-10-11 01:45:55 -05:00
										 |  |  |     def install | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |       Debrew.debrew { super } | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-26 19:42:11 -05:00
										 |  |  |     def patch | 
					
						
							|  |  |  |       Debrew.debrew { super } | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |     def test | 
					
						
							|  |  |  |       Debrew.debrew { super } | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-02-07 18:58:41 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |   class Menu | 
					
						
							|  |  |  |     Entry = Struct.new(:name, :action) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     attr_accessor :prompt, :entries | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def initialize | 
					
						
							|  |  |  |       @entries = [] | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def choice(name, &action) | 
					
						
							|  |  |  |       entries << Entry.new(name.to_s, action) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def self.choose | 
					
						
							|  |  |  |       menu = new | 
					
						
							|  |  |  |       yield menu | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       choice = nil | 
					
						
							|  |  |  |       while choice.nil? | 
					
						
							|  |  |  |         menu.entries.each_with_index { |e, i| puts "#{i+1}. #{e.name}" } | 
					
						
							|  |  |  |         print menu.prompt unless menu.prompt.nil? | 
					
						
							| 
									
										
										
										
											2012-02-21 01:14:02 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-06 15:45:52 +08:00
										 |  |  |         input = $stdin.gets || exit | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |         input.chomp! | 
					
						
							| 
									
										
										
										
											2014-03-14 13:03:51 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |         i = input.to_i | 
					
						
							|  |  |  |         if i > 0
 | 
					
						
							|  |  |  |           choice = menu.entries[i-1] | 
					
						
							| 
									
										
										
										
											2014-03-13 10:05:55 -05:00
										 |  |  |         else | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |           possible = menu.entries.find_all { |e| e.name.start_with?(input) } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           case possible.size | 
					
						
							|  |  |  |           when 0 then puts "No such option" | 
					
						
							|  |  |  |           when 1 then choice = possible.first | 
					
						
							|  |  |  |           else puts "Multiple options match: #{possible.map(&:name).join(" ")}" | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2014-03-13 10:05:55 -05:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |       choice[:action].call | 
					
						
							| 
									
										
										
										
											2014-03-13 10:05:55 -05:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |   class << self | 
					
						
							| 
									
										
										
										
											2016-09-23 18:13:48 +02:00
										 |  |  |     alias original_raise raise | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @active = false | 
					
						
							|  |  |  |   @debugged_exceptions = Set.new | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def self.active? | 
					
						
							|  |  |  |     @active | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   class << self | 
					
						
							|  |  |  |     attr_reader :debugged_exceptions | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def self.debrew | 
					
						
							|  |  |  |     @active = true | 
					
						
							|  |  |  |     Object.send(:include, Raise) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     begin | 
					
						
							|  |  |  |       yield | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |     rescue SystemExit | 
					
						
							|  |  |  |       original_raise | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |     rescue Exception => e | 
					
						
							|  |  |  |       debug(e) | 
					
						
							|  |  |  |     ensure | 
					
						
							|  |  |  |       @active = false | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def self.debug(e) | 
					
						
							|  |  |  |     original_raise(e) unless active? && | 
					
						
							|  |  |  |                              debugged_exceptions.add?(e) && | 
					
						
							|  |  |  |                              try_lock | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     begin | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |       puts e.backtrace.first.to_s | 
					
						
							| 
									
										
										
										
											2016-08-26 16:04:47 +02:00
										 |  |  |       puts Formatter.error(e, label: e.class.name) | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |       loop do | 
					
						
							|  |  |  |         Menu.choose do |menu| | 
					
						
							|  |  |  |           menu.prompt = "Choose an action: " | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           menu.choice(:raise) { original_raise(e) } | 
					
						
							| 
									
										
										
										
											2016-09-20 22:03:08 +02:00
										 |  |  |           menu.choice(:ignore) { return :ignore } if e.is_a?(Ignorable) | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |           menu.choice(:backtrace) { puts e.backtrace } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-20 22:03:08 +02:00
										 |  |  |           if e.is_a?(Ignorable) | 
					
						
							|  |  |  |             menu.choice(:irb) do | 
					
						
							|  |  |  |               puts "When you exit this IRB session, execution will continue." | 
					
						
							|  |  |  |               set_trace_func proc { |event, _, _, id, binding, klass| | 
					
						
							|  |  |  |                 if klass == Raise && id == :raise && event == "return" | 
					
						
							|  |  |  |                   set_trace_func(nil) | 
					
						
							|  |  |  |                   synchronize { IRB.start_within(binding) } | 
					
						
							|  |  |  |                 end | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               return :ignore | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |           menu.choice(:shell) do | 
					
						
							|  |  |  |             puts "When you exit this shell, you will return to the menu." | 
					
						
							|  |  |  |             interactive_shell | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2012-02-21 01:14:02 -06:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |     ensure | 
					
						
							|  |  |  |       unlock | 
					
						
							| 
									
										
										
										
											2012-02-21 01:14:02 -06:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2014-09-18 14:16:07 -05:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2012-02-21 01:14:02 -06:00
										 |  |  | end |