Tuesday, February 19, 2008
Rake: Task Overwriting
Update at bottom
By default Rake Tasks append behavior every time they are defined. The following example shows that both definitions are executed.
I like this behavior, but sometimes you want to overwrite a task instead of appending to what's already there.
When you no longer want the existing behavior the
The overwrite method is good, but sometimes you want to redefine the task using one of the specialized Rake tasks. I recently wanted to redefine the test task, so I created the
Hopefully you wont need this type of thing very often, but it can be handy when you want to overwrite a task that has been previously by a framework you've included.
Update below...
Ola Bini pointed out that I'm not clearing the prerequisites. Clearing the prerequisites is something you can do without any modifications to rake.
Also, if you want prerequisites cleared as part of overwrite or abandon, you can easily add it to both tasks.
By default Rake Tasks append behavior every time they are defined. The following example shows that both definitions are executed.
task :the_task do
p "one"
end
task :the_task do
p "two"
end
Rake::Task[:the_task].invoke
# >> "one"
# >> "two"
I like this behavior, but sometimes you want to overwrite a task instead of appending to what's already there.
When you no longer want the existing behavior the
overwrite method can come in handy.
@actions.clear
enhance(&block)
end
end
task :the_task do
p "one"
end
Rake::Task[:the_task].overwrite do
p "two"
end
Rake::Task[:the_task].invoke
# >> "two"
The overwrite method is good, but sometimes you want to redefine the task using one of the specialized Rake tasks. I recently wanted to redefine the test task, so I created the
abandon method to remove the existing definition.
@actions.clear
end
end
task :the_task do
p "one"
end
Rake::Task[:the_task].abandon
Rake::TestTask.new(:the_task) do |t|
t.libs << "test"
t.pattern = 'test/**/*_test.rb'
t.verbose = true
end
Rake::Task[:the_task].invoke
# >> Expectations ..................
# >> Finished in 0.00442 seconds
# >>
# >> Success: 18 fulfilled
Hopefully you wont need this type of thing very often, but it can be handy when you want to overwrite a task that has been previously by a framework you've included.
Update below...
Ola Bini pointed out that I'm not clearing the prerequisites. Clearing the prerequisites is something you can do without any modifications to rake.
Rake::Task[:task_name].prerequisites.clearAlso, if you want prerequisites cleared as part of overwrite or abandon, you can easily add it to both tasks.
@actions.clear
prerequisites.clear
enhance(&block)
end
prerequisites.clear
@actions.clear
end
endLabels: rake
Comments:
<< Home
I've been thinking about adding an explicit API in rake to do something similar to your overwrite and abandon examples. The thing that makes me pause is that is doesn't play nice with plugins. Its one thing to clear a task as a project owner, since you are assuming responsibility for the entire project. However, as writer of a Rakefile module (such as the .rake files in a rails project), using abandon or overwrite clearly has the potential of overwriting someone else's overwrites. I've not come up with a good solution for that.
Hello Jim, thanks for the comment.
I think your concern is a valid one, but no different than the same threat that Open Classes pose. With great power...
I also think you might as well add overwrite and abandon to Rake since the cat's already out of the bag. RSpec wrote their own redefine_task method and after I finished with my blog post, I found someone else who had written their own overwrite method. It's basically public knowledge, so adding it to the framework is the next logic step, IMHO.
Cheers, Jay
I think your concern is a valid one, but no different than the same threat that Open Classes pose. With great power...
I also think you might as well add overwrite and abandon to Rake since the cat's already out of the bag. RSpec wrote their own redefine_task method and after I finished with my blog post, I found someone else who had written their own overwrite method. It's basically public knowledge, so adding it to the framework is the next logic step, IMHO.
Cheers, Jay
Awesome post, to this day (more then 2 years of rails dev), I never understood why redefining a rake task didn't _redefine the rake task_. I guess I can see the benefit of appending the behavior. But It's not the first thing I would have thought, thanks!
Post a Comment
<< Home





