Search code examples
rubyrspecguard

Event Handler for Guard (on exit)?


I have a notification system that when guard-rspec fails it lights a LED red, and when it passes, it lights up green, that's all great, but I'm looking for a way to turn the light off if I exit (or guard crashes).

I was wondering if there is a way to catch an "On Exit" event and run some code?

Also, is there a way to catch a exception (like an 'on error' event)?


Solution

  • Use Guard Callbacks

    Per https://github.com/guard/guard/wiki/Create-a-guard, the #stop method is called when Guard quits.

    The Callback section of Guard's readme indicates you can hook into the #stop method before or after it runs. There is no indication that this method will run anything if Guard crashes, so it may only work for clean exits.

    Here's an untested example I would start with.

    # Guardfile
    
    require 'led'
    
    guard :rspec do
        watch('spec/*')
    
        callback(:stop_end) { set_led(:off) }
    end
    

    Use a Wrapper Script

    You could create a ruby script that runs Guard, blocks, and turns off the light once Guard finishes running, even by crashing.

    #!/usr/bin/env ruby
    # wrapper.rb
    
    require 'led'
    
    system("guard")
    set_led(:off)
    

    phoet's at_exit Suggestion

    Assuming whatever crashed Guard doesn't interfere with the at_exit callback, this method should work as well as the wrapper script.

    # Guardfile
    
    require 'led'
    
    at_exit { set_led(:off) }
    
    guard :rspec do
        watch('spec/*')
    end
    

    I tested this method by running Guard, then in a separate terminal...

    $ pkill -15 -f guard     # same as Ctrl-c, triggers at_exit
    $ pkill -9  -f guard     # kills ruby, does not trigger at_exit