June 19, 2011 ( ruby, development )

Automate your application's development environment with Guard

Do you find yourself repeating various actions over and over again in your development environment? Examples of such actions are restarting your application server for your Rails app every time you update a files that are loaded in memory and require a server restart for the changes to take effect. Maybe you are using Nanoc, a static site generator and would like it to automatically recompile your site every time a file is saved. Or maybe you are using a testing library such as RSpec and want to automatically run your tests every time you save a Ruby file.

There are lots of things that could be automated. Some tools come with built-in utilities to take care of this (think of autotest, nanoc autocompile, etc), but they will all require their own separate terminal window.

Enter Guard

Guard is a RubyGem, written by Thibaud Guillaume-Gentil (@thibaudgg), that you could use to easily automate parts of your application’s development environment.

To show you what it can do, here’s an example: Let’s say we have a Ruby on Rails application, using Bundler to manage gem dependencies and RSpec as our testing library. Each of these bring with them repetitive actions. So let’s automate them.

We could use the following gems:

  • Guard::Rails
  • Guard::Bundler
  • Guard::RSpec

These gems are basically Guard “modules”. Simply add them to your Gemfile. Now create a Guardfile in your application’s root directory and add the following.

guard 'rails' do
  watch('Gemfile.lock')
  watch(%r{^(config|lib)/.*})
end

guard 'rspec' do
  watch('spec/spec_helper.rb') { "spec" }
  watch('config/routes.rb') { "spec/routing" }
  watch('app/controllers/application_controller.rb') {
    "spec/controllers"
  }
  watch(%r{^spec/.+_spec\.rb})
  watch(%r{^app/(.+)\.rb}) { |m| "spec/#{m[1]}_spec.rb" }
  watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" }
  watch(%r{^app/controllers/(.+)_(controller)\.rb}) { |m|
    ["spec/routing/#{m[1]}_routing_spec.rb",
    "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb",
    "spec/acceptance/#{m[1]}_spec.rb"]
  }
end

guard 'bundler' do
  watch('Gemfile')
end

Let’s go over what the above Guardfile + Guard Gems will do for us.

With Guard::Rails, if a file in the config or lib directories are updated, or the Gemfile.lock file gets updated, the rails app server will automatically be restarted. Normally, you would have to open the shell manually and restart the process yourself. With Guard::Rails, this will be done for you.

With Guard::RSpec, when you save for example a controller file, only that specific controller’s spec file will be run, rather than running all the tests. The same goes for models. You can customize this behavior to suit your needs. Another cool feature, which is particularly interesting when you’re working on gems that need to support multiple Ruby versions, is that you can pass in a hash of options to the guard 'rspec' method in the Guardfile. For example if you want to run the tests against MRI 1.9.2, 1.8.7, REE 1.8.7, JRuby and Rubinius, and you are using RVM, you could simply define the following:

guard 'rspec', :rvm => ['1.9.2', '1.8.7', 'ree', 'jruby', 'rbx'] do
  ...
end

Now every time Guard runs your tests, it’ll run them against the all defined Ruby versions and implementations.

With Guard::Bundler, it simply watches for changes in the Gemfile, and will re-bundle it when changes are made. Rather than having to manually go in to the terminal again to run bundle install, this will be done for you. Also, notice that the Guard::Rails has this line defined: watch('Gemfile.lock'). When Guard::Bundler runs the bundle install command, it’ll update the Gemfile.lock file, which means that dependencies have changed and that the Rails server will also be restarted automatically for you by Guard::Rails. Again, no need to go in to your terminal to restart it manually.

Another useful feature is that it supports growl notifications (or libnotify on Linux). So you could have a small notification pop up on your screen when tests run, or when the Rails server has been restarted, without having to check the shell.

Guard is very modular, and there are a bunch of modules available right out of the box that automate particular parts of your development environment. It is also easy to write your own Guard modules, refer to Guard’s README on GitHub for more information.

To Archive → Share twitter

Michael van Rooijen

Crafter of Ruby apps, and open source contributor.

I built and run HireFire.