Friday, January 13, 2012

Rake Fundamentals: rakefiles and tasks

Ok, what is Rake again? 

Rake is a collection of Ruby scripts that live deep within the bowels of your Ruby installation.  Since you made sure you checked the box that adds the Ruby stuff to your PATH variable as you stepped through the Ruby installer wizard, you now have easy access to your Ruby installation and all of the special scripts it contains right from the command line.  To make use of those Ruby scripts, you do a couple of things:

1) Create a rakefile, which is itself a ruby script containing named tasks you can run from the command line.

2) Run one or more of those tasks from the command line like so:

C:\sandbox\rakefun\> rake mytask

And what’s a rakefile? 

That command you just issued told rake to look for a file called c:\sandbox\rakefun\rakefile.rb and execute a task called ‘mytask’. You can call the rakefile something else if you want to, but if you name it “rakefile.rb”, you don’t have to include the “-f my_special_rakefile_name_because_im_a_unique_delicate_flower.rb” switch on the rake command line call – just less to type if you stick to the convention. It’s easy to create a rakefile: open up notepad, type in your tasks, save it as “rakefile.rb”, and you’re done. No compiling. No real need for fancy IDE’s, just any old text editor will do. I like Notepad2, and Komodo Edit is another nice free one with Ruby syntax highlighting. So, what exactly is in a rakefile?

tasks

The fundamental building block of a rakefile is the “task”.   Here’s a hello world rakefile that has one task in it called “:say_hi”.

require 'rake'

desc "My first rake task"
task :say_hi =>[] do
puts "Hello, dude!"
end

Ok, I fudged a little bit: when you open your editor to create your rakefile, you should actually require ‘rake’ at the beginning of the script.  This tells Ruby to find the rake.rb ruby script and pull it into your rakefile when Ruby parses it.  Ruby parses your rakefile any time you make a call to it with the rake keyword on the command line.

Rake provides a keyword called “task”.  The task keyword is actually just a call to a method named “task()” that lives somewhere in the rake.rb ruby script.  But through the magic of Ruby, the task() method call in your rakefile is formatted as you see above.  Takes a little getting used to.  Every time you call a task in your rakefile, Ruby parses the entire file, and all the task() method calls get executed.  But don’t worry – as each task() method call is executed, Ruby is just looking through the rakefile to gather up the name of each task, and the code that Ruby should run when that task name is called from the command line.  So if we had “:task1” and “:task2” in our rakefile, and we called “rake task1” from the command line, Ruby would know that we have both :task1 and :task2 available, but it would only run the code associated with task1.

There are two arguments being passed to task(), and if you’re not familiar with Ruby, they’re a little hard to distinguish:

1) The first argument is “:say_hi =>[]” – This is a Ruby hash object, which is just a collection of key/value pairs.  In this case the hash contains only one key/value pair.  The key is the symbol “:say_hi”, which by convention becomes the name of the task.  The value is “[]”, which is Ruby parlance for an empty array.  In more complex tasks, this array would contain the names of other tasks which should be prerequisites to this task.  Ruby is pretty forgiving, and rake takes advantage of that, so if you have no prerequisites you don’t actually have to include the “=>[]” part; and when you have one or more prerequisites, you can exclude the brackets and just supply a comma-separated list of task names.

2) The second argument is this highlighted block of code starting with “do” and ending with “end”:
task :say_hi =>[] do
  puts "Hello, dude!"
end

A code block is a special Ruby construct that you can think of like an anonymous method or a lambda.  When you call a rake task, rake first executes all the prerequisite tasks you listed in the array in the first argument, and then executes the code in the do…end code block.  If you only want to run prerequisite tasks without executing any other code, just don’t include a do…end code block.

The :say_hi task is called from the command line like this:

image

Get a list of tasks with rake -T

Tasks decorated with a “desc” are shown when you call “rake –T”, “rake –tasks”, or “rake –D” on the command line: 

image

Tasks with no “desc” are not shown in the task list, but can still be called from the command line, or used as prerequisites for other tasks.

Next time: Tasks with prerequisites.

No comments: