Extending notifiers for guard arduino (guarduino?)

72 views
Skip to first unread message

Amiel Martin

unread,
Mar 27, 2013, 1:57:02 PM3/27/13
to guar...@googlegroups.com
Hello,

I'd like guard to notify me when my test suite passes or fails by controlling an arduino with an rgb led.

Don't be turned off by my hipster interest in arduino. This message is not so much about arduino, but more
about how to make guard better for anyone interested in writing custom notifications.

My first approach involved a gem that would extend guard adding a notification.
While a bit hacky, this worked:

::Guard::Notifier::NOTIFIERS << [[:digirgb, ::Guard::Notifier::Digirgb]]

However, rspec forks a new process to run the tests, and my monkeypatch didn't make it.
Adding my Digirgb notifier directly to the guard source worked just fine, so I asked this question
http://stackoverflow.com/questions/15624429/how-do-a-i-write-a-custom-notifier-for-guard/15637555
and got a very helpful answer from Netzpirat.

I've got some thoughts on how to accomplish this, and I'd like some feedback on which direction(s) to go.

  • Send a pull request to guard/guard with my Digirgb notifier.
    While Netzpirat did say "I would not mind to merge a pull request for an exotic notifier", I still don't
    like this idea at all because it's not only fairly "exotic" but for a very specific kind of arduino (will only
    work with a digispark, and depends on a gem just for digispark), and it's still a bit finicky and I don't
    want guard maintainers to have to support that.
  • Create a wrapper gem for "arduino notifiers" (or maybe "hardware notifiers"), and write a notifier for
    guard that depends on the wrapper gem (this would be sort of like the listen gem).
    I like this option, but I'm not in a good position to maintain such a wrapper gem as I'm not very
    experienced with arduino and don't have a variety of devices to test with.
  • Write a "file" notifier for guard.
    This would be the most generic solution. The "file" notifier would write results to a file on each
    `notify`. This allows users of guard to run anything when that file is updated.
    Example:

    notification(:file, path: "tmp/guard_result")
    # Prototype with guard-shell.
    guard :shell do
      watch('tmp/guard_result') {
        # ...
      }
    end


    I've already started prototyping this, and it could be used for all sorts of things.
  • Add an API/standards to guard for notifier plugins.
    1. The first part is simple enough, there needs to be a way to add a notifier from a separate gem
        without having to modify a guard internal constant. This could be some sort of initialization
        api call, or automatic constant lookup like Guard.get_guard_class
        (https://github.com/guard/guard/blob/master/lib/guard.rb#L390-L410).
    2. The harder part is dealing with the fact that some guards fork and reload guard (is this just
        guard-rspec? or are there others?). As Netzpirat pointed out, guard already has hacks in
        place to deal with this (https://github.com/guard/guard/blob/master/lib/guard/notifier.rb#L76-L92);
        guard sets a yaml serialized environment variable with information about available notifications.
        My only thought so far is to add a third option to the environment variable indicating libraries to
        load. However, that is just piling hacks on top of hacks.
    I guess the other option would be to figure out a way to fix the guard-rspec hack, but I think that
    is beyond the scope of my involvement. Can anyone explain to me why guard-rspec has to fork
    a separate process?

My favorite options are the last two (the file notifier and an api to add notifiers), and since the last one
has a bunch of hacks to deal with, I'm inclined to write the file notifier.

Anyway, does anyone have thoughts on this?


Thanks,

-Amiel

Michael Kessler

unread,
Mar 27, 2013, 4:26:28 PM3/27/13
to guar...@googlegroups.com
Amiel,

> Don't be turned off by my hipster interest in arduino.

I love the idea!

> • Write a "file" notifier for guard.

That's already possible with Guard: You can set the `device` option on the logger like

logger device: '~/guard.log'

on your Guardfile.

> Can anyone explain to me why guard-rspec has to fork a separate process?

I see two reasons for this:

1. To ensure a clean environment for each test run.
2. Use some kind of environment preloader like spork, zeus, spring.

> My favorite options are the last two (the file notifier and an api to add notifiers), and since the last one
> has a bunch of hacks to deal with, I'm inclined to write the file notifier.

If the logger doesn't work for you for some reason, I'd go the file notifier route, because it simpler and a more general solution.

Michael

Amiel Martin

unread,
Mar 27, 2013, 7:13:37 PM3/27/13
to guar...@googlegroups.com
Michael,

Thanks again for your prompt responses. Here's what I've found out:

>    logger device: '~/guard.log' 

Unfortunately this won't do it for me. The log works fine, but it doesn't include test results.

No biggie though, I wrote the file notifier option. See https://github.com/guard/guard/pull/407.

-Amiel

PS Thanks for explaining the reasoning behind RSpec fork. That actually does makes sense.

Amiel Martin

unread,
Mar 27, 2013, 7:16:26 PM3/27/13
to guar...@googlegroups.com
BTW, for those that are curious. Here's how I'm using it: https://gist.github.com/amiel/5258723
It requires a [digispark](http://digistump.com/product.php?id=1) with the [rgb shield](http://digistump.com/product.php?id=3).

-Amiel
Reply all
Reply to author
Forward
0 new messages