-
Notifications
You must be signed in to change notification settings - Fork 12
Hooks and callbacks
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.
You can set your callback for a specific Guard in your Guardfile with the Guard::DSL.callback method. There are two ways to define your callbacks:
The first argument to Guard::Dsl#callback is the hook of interest. The block contains the code to run. For example, to have Guard open TextMate when it first starts up:
# Guardfile
guard 'rspec' do
watch(...) { ... }
callback(:start_begin) { `mate .` }
endIf you have more complex code to run, you can create a separate object to contain that code. In order for the callback to run, it must have a #call (or .call if it's a module) method that receives the class of the Guard associated with the callback, the hook event, and a splat of other arguments. For Guard::Dsl#callback, you pass the object (or the module) and the hook(s) you are interested in. Here is an example of a Timer plugin.
# Guardfile
class Guard::Timer
def times
@times ||= Hash.new({})
end
def call(guard_class, event, *args)
event.to_s =~ /(.*)_(begin|end)/
times[$1][$2] = Time.now
puts "#{guard_class} received these args: #{args} for #{event}"
if $2 == 'end'
time = times[$1]['end'] - times[$1]['begin']
puts "#{guard_class} took #{time} seconds to run"
end
end
end
guard 'rspec' do
watch(...) { ... }
callback(Timer.new, [:start_begin, :start_end])
endFor the default "_begin" hooks, the *args that are passed to #call are the matched files that Guard has detected changes on. For the default "_end" hooks, *args are the results of the Guard action that was executed.
Currently, callbacks are fired only if the given plugin implements the related method, e.g. Guard-Rspec doesn't currently implement stop, so callbacks for :stop_begin and :stop_end won't be called. The quick workaround is to add these methods through monkey-patching, but of course, caution is advised when doing so:
# Required for instance_methods to have actual methods
require 'guard/rspec'
module ::Guard
class RSpec < Plugin
# Always check in case a future version of the plugin
# implements the method
unless instance_methods.include?(:stop)
def stop; end
end
end
end
guard 'rspec' do
watch(...) { ... }
callback(Foo.action, [:stop_begin, :stop_end]) # now works
endIf you are developing a Guard and want end users or other gems to be able to hook into certain parts of your code, then you can create a custom hook with the #hook method. You define the hook's name with either a symbol or string. If passed a symbol, the hook name will be the name of the calling method with the symbol appended. If passed a string, the hook name will be the string.
module Guard
class MyGuard < Plugin
def start
# some code
hook :custom_hook_1 # this hook's name will be :start_custom_hook_l
# more code
hook "custom_hook_2" # this hook's name will be :custom_hook_2
# rest of code
end
# the default hooks :start_begin and :start_end will still be available
end
endThis wiki and the Guard README document contains a lot of information, please take your time and read these instructions carefully.
If you run into any trouble, you may start by understanding how Guard works.
We provide detailed changes for each Guard release.
Be sure to read the CONTRIBUTING guidelines before reporting a new Guard issue or open a pull request.
If you have any questions about the Guard usage or want to share some information with the Guard community, please go to one of the following places:
- Google+ community
- Google group
- StackOverflow
- IRC channel
#guard(irc.freenode.net) for chatting
Intro
Installation
- System Notifications
- Terminal Colors on Windows
- Add Readline support to Ruby on Mac OS X
- Which Growl library should I use
- Efficient Filesystem Handling
Getting Started
- List of Guard Commands
- Command Line Options for Guard
- List of available Guards
- Guardfile examples
- Run Guard within RubyMine
- Guardfile-DSL / Configuring-Guard
- Configuration Files
- Interacting with Guard
- Guard Signals
Troubleshooting
Advanced use of Guard
Cookbooks
Development