Friday, January 13, 2012

Rake Fundamentals: tasks with prerequisites

Rake tasks can have other tasks as prerequisites.  That means that a tasks prerequisites are executed before the task itself when the task is called from the command line.  Just like Nant, if you have a lot of small tasks you often run together, it’s convenient to roll them up into one task with prerequisites.  Let’s use rake to rock out:

image

require 'rake'

desc "open guitar case and get guitar"
task :get_axe do
puts "opening guitar case"
puts "grabbing telecaster"
end

desc "plug guitar into amp"
task :crank_up do
puts "plugging into 1959 fender tremolux"
puts "turning up volume"
end

desc "play A chord"
task :play_a do
puts "playing A chord"
end

desc "play D chord"
task :play_d do
puts "playing D chord"
end

desc "play E chord"
task :play_e do
puts "playing E chord"
end

desc "bask in the glory of adulation"
task :take_bow do
puts "taking a bow"
puts "winking at the girl in the front row"
end

desc "give the people what they want"
task :rock_the_house => [:get_axe, :crank_up, :play_a, :play_d,
:play_a, :play_e, :take_bow]

This rakefile defines these tasks:

image

And you could call each of these tasks individually if you wanted to.  But we want to rock the house, right?  So all we need to do is call “rake rock_the_house”.  According to the prerequisite list in the :rock_the_house task, rocking the house should consist of getting out our axe, cranking up, jamming some chords in this order: ADAEA, and bowing to a standing ovation.  Let’s give it a try and see what happens:

image

Our rock_the_house task ran all the prerequisites, except it didn’t play all the chords we told it to play – we only played ADE, not ADAEA.  LAME!  That’s because rake keeps track of tasks it has executed, and by default will only execute them once.  That might be cool for some tasks, but we want to play the blues, so we have to re-enable our “play_a” task every time we execute it so that we can execute it again.  Let’s fix our rakefile by creating a “play_the_blues” task that knows how to play our chords correctly:

require 'rake'

desc "open guitar case and get guitar"
task :get_axe do
puts "opening guitar case"
puts "grabbing telecaster"
end

desc "plug guitar into amp"
task :crank_up do
puts "plugging into 1959 fender tremolux"
puts "turning up volume"
end

desc "play A chord"
task :play_a do
puts "playing A chord"
end

desc "play D chord"
task :play_d do
puts "playing D chord"
end

desc "play E chord"
task :play_e do
puts "playing E chord"
end

desc "bask in the glory of adulation"
task :take_bow do
puts "taking a bow"
puts "winking at the girl in the front row"
end

task :play_the_blues do
Rake::Task[:play_a].invoke
Rake::Task[:play_a].reenable

Rake::Task[:play_d].invoke

Rake::Task[:play_a].invoke
Rake::Task[:play_a].reenable

Rake::Task[:play_e].invoke

Rake::Task[:play_a].invoke
end

desc "give the people what they want"
task :rock_the_house => [:get_axe, :crank_up, :play_the_blues, :take_bow]

Sometimes instead of calling a task as a prerequisite, you want to invoke it directly from within another task.  Calling the invoke() method on Rake::Task[] is how you do that.  Once you’ve called a task, you can reenable it to be called again by using Rake::Task[].reenable().  We’ve modified our “rock_the_house” task by calling our new “play_the_blues” task as a prerequisite.  Notice that since we didn’t give our “play_the_blues” task a description, it doesn’t show up on the task list when you type “rake –T”.  But it’s still available for use.  Also, notice that we didn’t provide a do…end block to our “rock_the_house” task.  Since we defined everything we need for rocking the house in our other tasks, we only needed to provide the “rock_the_house” task with prerequisites.  Let’s see what happens now:

image

Perfect!  All the chords get played in the right order.  We’ve got a single task to call from the command line that can do all the things we want it to do. 

Next up: directory and file tasks

No comments: