Overriding Rake Tasks

July 30th, 2007

It seems that I’m lucky cause the project I’m currently working on forces me to deal with non-typical problems again and again. This time I need to override one of the default Rails Rake tasks behaviour. For some reason I thought that I’ll simply be able to do it somehow, but it appeared that Rake doesn’t allow that and I’ve ended up with another plugin :)

I won’t describe why I needed to override Rake tasks right now, I’m going to post another article about it latter, let’s just take it as a matter of course for now.

First of all I’ve tried to simply define a new task with the same name as the existing one and thought that it will work, but Rake adds the new task to the queue in this case and runs both (the new one after the original one).

Then I’ve tried to read more about Rake and found out that one can add “prerequisites” for the tasks (even for exisitng ones) like this:

task :test => ['pre_test_task1', 'pre_test_task2']

While that’s very helpfull, it doesn’t solve my problem. As usual I’ve googled for a solution and found Matthew Bass’s blog post. Actually Mattew described a working solution, but I didn’t like the way it looked. To override a task one have to add the new tasks to the Rakefile like this (we’re overriding Rails “test” task):

remove_task :test task :test do #new task code here end

I didn’t like the idea of adding new tasks to the Rakefile and the “remove_task” method call before each task. So I’ve spent a couple of hours messing with Rake sources and finally written an “override_task” method that actually deleted existing task with the given name and defined a new one. It can be used like this:

override_task :test do #new task code here end

You can put this in you app’s lib/tasks as usual, or add it to one of your plugins’ tasks. It works with a namespace too of course:

namespace :db do override_task :migrate do #new migration code here end end

Then, I thought if it could be made as a plugin. In order to make it work, the code written should be loaded before the tasks and it means that Rakefile should be modified to load it. I’ve recently messed with app_config plugin by Daniel Owsiański and noticed the way it adds a line to environment.rb during installation. I’ve simply copied the idea and the plugin was ready! During installation it adds a line to the Rakefile that loads the plugin itself.

To play with it do the usual

script/plugin install http://tools.assembla.com/svn/rails_plugins/override_rake_task

Leave a Reply