Rails: December 2007 Archives

Loading your Capistrano 2 recipes

|

I love, love, love Capistrano 2. For the person in perpetual need of structure and symmetry, as I am, Cap 2 namespaces are a blessing.

However, there is another feature of Cap 2 that is almost as cool as namespaces... The ability to easily load your custom recipes. Let's look at a quick example...

First, you need to setup your project for Cap 2:

  
  sandbox > capify .
  

Once you've done that, you'll notice a new file in your project root named Capfile. The basic Capfile code is pretty simple:

  
    load 'deploy' if respond_to?(:namespace) # cap2 differentiator
    Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
    load 'config/deploy'
  

Notice that Cap 2 will look for recipes in each of your plugin directories. That's way cool. Also, take note that config/deploy.rb is the only other recipe that gets automatically loaded.

Now, if we take a little jaunt in our Wayback Machine to the beginning of this blog post, you'll remember that I love, nay, need symmetry. I think of Capistrano recipes as remote rake tasks. I realize that they can be so much more than that, but hey, humor me.

We store custom rake tasks in lib/tasks. So why not store our recipes in lib/recipes? Why indeed! I think we will.

First let's create our Solr recipe: lib/recipes/solr.rb:

  
   namespace :solr do
    desc "Start the solr server"
    task :start do
      puts "starting solr"
    end
  
    desc "Stop the solr server"
    task :stop do
      puts "stopping solr"
    end
  end 
  

Next, our monit recipe: lib/recipes/monit.rb:

  
  namespace :monit do
    desc "Start monit"
    task :start do
      puts "starting monit"
    end
  end
  

The final piece of the puzzle involves adding a single line to our Capfile:

  
    load 'deploy' if respond_to?(:namespace) # cap2 differentiator
    Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
    load 'config/deploy'

    # Load recipes from lib
    Dir['lib/recipes/*.rb'].each { |recipe| load(recipe) }
  

All we did was mirror the directive for loading plugins with a slight twist. Rather than looking in plugins directory, we focused our attention on lib/recipes.

And now, for the moment of truth:

  
  sandbox > cap -T
  .
  cap monit:start          # Start monit
  cap solr:start           # Start the solr server
  cap solr:stop            # Stop the solr server
  sandbox > 
  

Ahh! Symmetry achieved.