# typed: ignore # Copyright (c) 2015 Sqreen. All Rights Reserved. # Please refer to our terms for more information: https://www.sqreen.com/terms.html require 'sqreen/graft' require 'sqreen/graft/hook_point' require 'sqreen/graft/callback' module Sqreen module Graft class Hook DEFAULT_STRATEGY = Sqreen::Graft::HookPoint::DEFAULT_STRATEGY @hooks = {} def self.[](hook_point, strategy = DEFAULT_STRATEGY) @hooks[hook_point] ||= new(hook_point, nil, strategy) end def self.add(hook_point, strategy = DEFAULT_STRATEGY, &block) self[hook_point, strategy].add(&block) end def self.ignore Thread.current[:sqreen_hook_entered] = true yield ensure Thread.current[:sqreen_hook_entered] = false end attr_reader :point def initialize(hook_point, dependency_test = nil, strategy = DEFAULT_STRATEGY) @disabled = false @point = hook_point.is_a?(HookPoint) ? hook_point : HookPoint.new(hook_point, strategy) @before = [] @after = [] @raised = [] @ensured = [] @dependency_test = dependency_test || Proc.new { point.exist? } end def dependency? @dependency_test.call if @dependency_test end def add(&block) tap { instance_eval(&block) } end def callback_name(whence, tag = nil) "#{point}@#{whence}" << (tag ? ":#{tag}" : "") end def before(tag = nil, opts = {}, &block) return @before if block.nil? @before << Callback.new(callback_name(:before, tag), opts, &block) @before.sort_by!(&:rank) end def after(tag = nil, opts = {}, &block) return @after if block.nil? @after << Callback.new(callback_name(:after, tag), opts, &block) @after.sort_by!(&:rank) end def raised(tag = nil, opts = {}, &block) return @raised if block.nil? @raised << Callback.new(callback_name(:raised, tag), opts, &block) @raised.sort_by!(&:rank) end def ensured(tag = nil, opts = {}, &block) return @ensured if block.nil? @ensured << Callback.new(callback_name(:ensured, tag), opts, &block) @ensured.sort_by!(&:rank) end def depends_on(&block) @dependency_test = block end def enable @disabled = false end def disable @disabled = true end def disabled? @disabled end def install unless point.exist? Sqreen::Graft.logger.debug { "[#{Process.pid}] #{point} not found" } return end Sqreen::Graft.logger.debug { "[#{Process.pid}] Hook #{point}: installing" } point.install('sqreen_hook', &Sqreen::Graft::Hook.wrapper(self)) end def uninstall unless point.exist? Sqreen::Graft.logger.debug { "[#{Process.pid}] #{point} not found" } return end Sqreen::Graft.logger.debug { "[#{Process.pid}] Hook #{point}: uninstalling" } point.uninstall('sqreen_hook', &Sqreen::Graft::Hook.wrapper(self)) end def clear @before = [] @after = [] @raised = [] @ensured = [] end end end end if RUBY_VERSION =~ /^2\./ load File.join(__dir__, 'hook.ruby_2.rb') else load File.join(__dir__, 'hook.ruby_3.rb') end