master/lib/guard/hook.rb

117 lines
3.6 KiB
Ruby
Raw Normal View History

2011-04-10 23:08:43 +00:00
module Guard
2011-09-20 12:42:32 +00:00
# Guard has a hook mechanism that allows you to insert callbacks for individual Guards.
# By default, each of the Guard instance methods has a "_begin" and an "_end" hook.
# For example, the Guard::Guard#start method has a :start_begin hook that is run immediately
# before Guard::Guard#start and a :start_end hook that is run immediately after Guard::Guard#start.
#
# Read more about [hooks and callbacks on the wiki](https://github.com/guard/guard/wiki/Hooks-and-callbacks).
#
2011-04-10 23:08:43 +00:00
module Hook
2011-09-20 12:42:32 +00:00
# The Hook module gets included.
#
# @param [Class] base the class that includes the module
#
2011-04-10 23:08:43 +00:00
def self.included(base)
base.send :include, InstanceMethods
end
2011-09-20 12:42:32 +00:00
# Instance methods that gets included in the base class.
#
2011-04-10 23:08:43 +00:00
module InstanceMethods
2011-09-20 12:42:32 +00:00
# When +event+ is a Symbol, {#hook} will generate a hook name
# by concatenating the method name from where {#hook} is called
# with the given Symbol.
2011-09-20 12:42:32 +00:00
#
# @example Add a hook with a Symbol
# def run_all
# hook :foo
# end
2011-09-20 12:42:32 +00:00
#
# Here, when {Guard::Guard#run_all} is called, {#hook} will notify callbacks
# registered for the "run_all_foo" event.
#
2011-09-20 12:42:32 +00:00
# When +event+ is a String, {#hook} will directly turn the String
# into a Symbol.
2011-09-20 12:42:32 +00:00
#
# @example Add a hook with a String
# def run_all
# hook "foo_bar"
# end
2011-09-20 12:42:32 +00:00
#
# When {Guard::Guard#run_all} is called, {#hook} will notify callbacks
# registered for the "foo_bar" event.
#
2011-09-20 12:42:32 +00:00
# @param [Symbol, String] event the name of the Guard event
# @param [Array] args the parameters are passed as is to the callbacks registered for the given event.
#
def hook(event, *args)
hook_name = if event.is_a? Symbol
2011-09-20 12:42:32 +00:00
calling_method = caller[0][/`([^']*)'/, 1]
"#{ calling_method }_#{ event }"
else
event
end.to_sym
2011-04-10 23:08:43 +00:00
2011-09-20 12:42:32 +00:00
UI.debug "Hook :#{ hook_name } executed for #{ self.class }"
Hook.notify(self.class, hook_name, *args)
2011-04-10 23:08:43 +00:00
end
end
class << self
2011-09-20 12:42:32 +00:00
# Get all callbacks
#
2011-04-10 23:08:43 +00:00
def callbacks
@callbacks ||= Hash.new { |hash, key| hash[key] = [] }
end
2011-09-20 12:42:32 +00:00
# Add a callback.
#
# @param [Block] listener the listener to notify
# @param [Guard::Guard] guard_class the Guard class to add the callback
# @param [Array<Symbol>] events the events to register
#
def add_callback(listener, guard_class, events)
_events = events.is_a?(Array) ? events : [events]
2011-04-10 23:08:43 +00:00
_events.each do |event|
callbacks[[guard_class, event]] << listener
end
end
2011-09-20 12:42:32 +00:00
# Checks if a callback has been registered.
#
# @param [Block] listener the listener to notify
# @param [Guard::Guard] guard_class the Guard class to add the callback
# @param [Symbol] event the event to look for
#
2011-04-10 23:08:43 +00:00
def has_callback?(listener, guard_class, event)
callbacks[[guard_class, event]].include?(listener)
2011-04-10 23:08:43 +00:00
end
2011-09-20 12:42:32 +00:00
# Notify a callback.
#
# @param [Guard::Guard] guard_class the Guard class to add the callback
# @param [Symbol] event the event to trigger
# @param [Array] args the arguments for the listener
#
def notify(guard_class, event, *args)
2011-04-10 23:08:43 +00:00
callbacks[[guard_class, event]].each do |listener|
listener.call(guard_class, event, *args)
2011-04-10 23:08:43 +00:00
end
end
2011-09-20 12:42:32 +00:00
# Reset all callbacks
#
def reset_callbacks!
2011-04-10 23:08:43 +00:00
@callbacks = nil
end
2011-09-20 12:42:32 +00:00
2011-04-10 23:08:43 +00:00
end
2011-04-10 23:08:43 +00:00
end
end