mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
Add ignorable module
This commit is contained in:
parent
586d25a522
commit
8b808308c2
@ -3,10 +3,7 @@
|
||||
|
||||
require "mutex_m"
|
||||
require "debrew/irb"
|
||||
require "warnings"
|
||||
Warnings.ignore(/warning: callcc is obsolete; use Fiber instead/) do
|
||||
require "continuation"
|
||||
end
|
||||
require "ignorable"
|
||||
|
||||
# Helper module for debugging formulae.
|
||||
#
|
||||
@ -14,31 +11,6 @@ end
|
||||
module Debrew
|
||||
extend Mutex_m
|
||||
|
||||
# Marks exceptions which can be ignored and provides
|
||||
# the ability to jump back to where it was raised.
|
||||
module Ignorable
|
||||
attr_accessor :continuation
|
||||
|
||||
def ignore
|
||||
continuation.call
|
||||
end
|
||||
end
|
||||
|
||||
# Module for allowing to ignore exceptions.
|
||||
module Raise
|
||||
def raise(*)
|
||||
callcc do |continuation|
|
||||
super
|
||||
rescue Exception => e # rubocop:disable Lint/RescueException
|
||||
e.extend(Ignorable)
|
||||
e.continuation = continuation
|
||||
super(e)
|
||||
end
|
||||
end
|
||||
|
||||
alias fail raise
|
||||
end
|
||||
|
||||
# Module for allowing to debug formulae.
|
||||
module Formula
|
||||
def install
|
||||
@ -106,28 +78,28 @@ module Debrew
|
||||
|
||||
class << self
|
||||
extend Predicable
|
||||
alias original_raise raise
|
||||
attr_predicate :active?
|
||||
attr_reader :debugged_exceptions
|
||||
end
|
||||
|
||||
def self.debrew
|
||||
@active = true
|
||||
Object.include Raise
|
||||
Ignorable.hook_raise
|
||||
|
||||
begin
|
||||
yield
|
||||
rescue SystemExit
|
||||
original_raise
|
||||
raise
|
||||
rescue Exception => e # rubocop:disable Lint/RescueException
|
||||
e.ignore if debug(e) == :ignore # execution jumps back to where the exception was thrown
|
||||
ensure
|
||||
Ignorable.unhook_raise
|
||||
@active = false
|
||||
end
|
||||
end
|
||||
|
||||
def self.debug(e)
|
||||
original_raise(e) if !active? || !debugged_exceptions.add?(e) || !try_lock
|
||||
raise(e) if !active? || !debugged_exceptions.add?(e) || !try_lock
|
||||
|
||||
begin
|
||||
puts e.backtrace.first.to_s
|
||||
@ -137,15 +109,15 @@ module Debrew
|
||||
Menu.choose do |menu|
|
||||
menu.prompt = "Choose an action: "
|
||||
|
||||
menu.choice(:raise) { original_raise(e) }
|
||||
menu.choice(:ignore) { return :ignore } if e.is_a?(Ignorable)
|
||||
menu.choice(:raise) { raise(e) }
|
||||
menu.choice(:ignore) { return :ignore } if e.is_a?(Ignorable::ExceptionMixin)
|
||||
menu.choice(:backtrace) { puts e.backtrace }
|
||||
|
||||
if e.is_a?(Ignorable)
|
||||
if e.is_a?(Ignorable::ExceptionMixin)
|
||||
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"
|
||||
if klass == Object && id == :raise && event == "return"
|
||||
set_trace_func(nil)
|
||||
synchronize { IRB.start_within(binding) }
|
||||
end
|
||||
|
58
Library/Homebrew/ignorable.rb
Normal file
58
Library/Homebrew/ignorable.rb
Normal file
@ -0,0 +1,58 @@
|
||||
# typed: false
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "warnings"
|
||||
Warnings.ignore(/warning: callcc is obsolete; use Fiber instead/) do
|
||||
require "continuation"
|
||||
end
|
||||
|
||||
# Provides the ability to optionally ignore errors raised and continue execution.
|
||||
#
|
||||
# @api private
|
||||
module Ignorable
|
||||
# Marks exceptions which can be ignored and provides
|
||||
# the ability to jump back to where it was raised.
|
||||
module ExceptionMixin
|
||||
attr_accessor :continuation
|
||||
|
||||
def ignore
|
||||
continuation.call
|
||||
end
|
||||
end
|
||||
|
||||
def self.hook_raise
|
||||
Object.class_eval do
|
||||
alias_method :original_raise, :raise
|
||||
|
||||
def raise(*)
|
||||
callcc do |continuation|
|
||||
super
|
||||
rescue Exception => e # rubocop:disable Lint/RescueException
|
||||
unless e.is_a?(ScriptError)
|
||||
e.extend(ExceptionMixin)
|
||||
e.continuation = continuation
|
||||
end
|
||||
super(e)
|
||||
end
|
||||
end
|
||||
|
||||
alias_method :fail, :raise
|
||||
end
|
||||
|
||||
return unless block_given?
|
||||
|
||||
yield
|
||||
unhook_raise
|
||||
end
|
||||
|
||||
def self.unhook_raise
|
||||
Object.class_eval do
|
||||
# False positive - https://github.com/rubocop/rubocop/issues/5022
|
||||
# rubocop:disable Lint/DuplicateMethods
|
||||
alias_method :raise, :original_raise
|
||||
alias_method :fail, :original_raise
|
||||
# rubocop:enable Lint/DuplicateMethods
|
||||
undef :original_raise
|
||||
end
|
||||
end
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user