Saturday, January 14, 2012

Rake Fundamentals: directory tasks

A build system is about building software.  And on a purely mechanical level, the work of building software is largely about creating files and moving them around.  The task keyword is the general workhorse for doing all kinds of things in Rake.  But you can create specialized tasks focused on automating particular things.  Rake comes with a couple of special kinds of tasks for managing directories and files. 

The directory task

Remember how the keyword “task” is really just a call to a method named “task()”?  Well the “directory” keyword is very similar – it’s really just a call to a method named “directory()”.  “directory” is a special kind of task that has one main purpose: it creates the directory it names if that directory doesn’t exist.  You don’t need to provide a do…end block parameter to a directory task, just a directory name.  Here’s a little rakefile to illustrate what I mean:

require 'rake'

BIN_DIR       = "source/bin"
PACKAGE_DIR   = "package"

desc "create a #{BIN_DIR} directory"
directory BIN_DIR

desc "create a #{PACKAGE_DIR} directory"
directory PACKAGE_DIR

There are a couple of new concepts here:  1) BIN_DIR and PACKAGE_DIR are Ruby constants.  By convention, Ruby constants are expressed in all caps with underscores.  2) The #{…} stuff is Ruby string replacement syntax.  So here’s what we see when we look at the task list for this rakefile:

image_thumb[1]

We have two tasks: one for creating a directory named “package”, and another for creating a directory named “source/bin”.  Since we typically work with compiled languages in the .NET world, there will usually be a compile step in our build process that will take care of creating a /bin directory for us.  But since we’re just pretending right now, I threw it in just for funsies.  You can call these tasks from the command line, and since the directories they name don’t initially exist, rake creates those directories:

image_thumb[4]

Making a directory is pretty simple – you just make the directory, and then you have the directory you wanted.  That’s why you don’t have to pass a do…end block to the directory task – the directory task already knows how to create a directory.  Ok, I hear what you’re saying: big deal.  And you’re right, calling “rake package” from the command line is not particularly useful when you could just call “md package” on the command line.  But directory tasks are very useful when you use them as prerequisites for file tasks.

Next up: file tasks

No comments: