Rails 3.1 engines: Part III – The environment

Rails 3.1 engines: Part III – The environment

Respect! If you made it till here (and attentively follow the preceding posts Rails 3.1 Engines: Part I – The engine and Rails 3.1 Engines: Part II – The gem), you definitely learned a lot already. Now in this posts I give you some final input on how to tweak your development environment to make your daily work with engines (and Rails in general) even more comfortable. :-)

Notifications from Guard

It’s nice to know that Guard always runs our tests in the background, but it doesn’t help much if we don’t check after every change whether they passed or not, which is cumbersome. But there’s a better solution: let yourself be notified about the test results automatically using Growl (Mac) or Libnotify (Linux)!

In addition, we don’t want Guard to use filesystem polling to detect changes! Instead, we can use the rb-fsevent (Mac) or rb-inotify (Linux); this will also stop the “Missing dependency ‘rb-fsevent’” warning from earlier.

Add this to your spec/dummy/Gemfile:

group :test do
  # Mac specific gems
  if RUBY_PLATFORM =~ /darwin/i
    gem 'rb-fsevent'
    gem 'growl'

  # Linux specific gems
  if RUBY_PLATFORM =~ /linux/i
    gem 'rb-inotify'
    gem 'libnotify'

Now restart Guard, and you will always be notified when the tests are run:

Using the great Guard&Spork combo for the host app AND an engine (or as many engines as you like)!

When developing engine(s) and host app in parallel, it’s good to always stay up to date from both whether its tests still pass while implementing cool features in any of them. Unfortunately, Guard-Rails was not built with this thought in mind, as it always defaults to the standard port 8990. But there’s a pretty simple way to tell Guard a custom port for every Spork&Guard combo so you can run as many of them in parallel as you like!

Basically, you simply have to tell Guard to fire up Spork on a specific port, and also tell RSpec to connect to it using exactly this port. You can tell this in the Guardfile:

spork_port = 8995
guard 'spork', rspec_port: spork_port do
  # ...

guard 'rspec', cli: "--drb --drb-port #{spork_port}" do
  # ...

I like to use ports from 8995 on, as by default Guard uses the ports from 8989 on for Test::Unit, RSpec, Cucumber, etc. That said, I recommend to stick to the default configuration for your host app, so you don’t break anything (for example, if a fellow developer already configured his environment to connect to the default ports).

There’s also a somewhat more elaborated technique to do this, just take a look at this gist, generously posted by mcmire.

I don’t use Guard!

Guard is great, but some people don’t like it. So you can also run several Sporks in parallel by using the --port argument:

$ spork --port 8995

Then connect to it with RSpec using the --drb --drb-port arguments:

$ rspec --drb --drb-port 8995

Notice: At the time being, it seems that this works for running many Guard&Spork combos at the same time, but only the latest started Guard actually connects to the DRB (Spork) – all previously started combos don’t, they start a new process for every test run, which slows things a bit down. So be sure to start the Guard&Spork combo, on which you’re actually working the heaviest, as the latest! Also, wait until the first Guard started, until you start another Guard; otherwise they tend to hang themselves. As soon as there’s a solution for these issues, I will post it here.

Controlling over-eager Guard, when to automatically run your tests!

While you can tell Guard pretty concisely which tests you want to run for which files in the Guardfile, sometimes it’s just not practical to have them run after every single file save. I have written a small shell script for this case which (un-) pauses Guard, and to make it really convenient, I activate this script using a keyboard shortcut specified in Alfred (you can also use similar free software like Quicksilver or Spark).

Take a look at the following two screenshots to get an idea on how to do something similar on your own computer!

The Script

And here in plain text, if you want to copy&paste:

local FILE = "/tmp/.guardpaused"
if [ -f FILE ]; then
  ps -ef | grep -i guard | grep -v grep | awk '{print $2}' | xargs kill -USR2
  rm FILE
  echo "Unpaused files modification listening."
  ps -ef | grep -i guard | grep -v grep | awk '{print $2}' | xargs kill -USR1
  touch FILE
  echo "Paused files modification listening."

The keyboard shortcut

From now on, just hit Cmd-Alt-P (or whatever key combination you specified) and Guard toggles its listening state:

Filter specs

Another nice trick is: if you don’t want Guard to run all your tests again and again (maybe while you’re working on a slightly more complex part of your code), then you can limit it to some specs marked with the :focus flag like so:

it "should load successfully", :focus do
  # Do some crazy stuff...

You can set this flag to every describe, context, it and specify block; you can even have them set on many of them at the same time! The larger your testing code base becomes, the more useful this feature surely will be.

Well, that’s all folks!

All in all, these two blog posts about engines and gems have gotten way longer than I expected, but there’s a whole lot of information bundled in one place now. I hope these posts will be useful to a lot of people and help them develop even better Rails applications in the future! Because: engines rule!! :-)

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>