An Alternate Way To Handle Task Dependencies In Custom Rake Tasks
Earlier today, I showed how to create a custom Rake task from the base TaskLib, so that we can use more than just simple “task :name” syntax for our rake tasks. In that example, I showed how to add explicit support for task dependencies by adding a second parameter to the initializer of our custom task:
1: attr_accessor :name, :task_dependencies
2:
3: def initialize(name = :some_name, task_dependencies = {})
4: @name = name
5: @task_dependencies = task_dependencies
6: yield self if block_given?
7: define
8: end
9:
10: def define
11: task name => task_dependencies do
12: #... some code here
13: end
14: end
</div> </div>
This code works, as shown earlier and provides the ability to execute dependency tasks prior to this one:
1: FooTask.new :somename, [:someothertask, :andanother] do
2: # ... task detail here
3: end
</div> </div>
It turns out there is a much less explicit, much more ruby-ish way to do the same thing. It seems that rake understands that the name of the task (the :name accessor) is to be treated as if it were a method. Since all methods in ruby have an implicit lambda block, as we’ve seen, we don’t have to include the explicit version of the :task_dependencies in our code. We can simplify the custom task and remove all of the :task_dependencies usage. Then we only need to call the => lamba when setting the name of the task in our rake file.
This example task, with no explicit :task_dependencies works the same as the example from the earlier post, today:
1: class FooTask < Rake::TaskLib
2:
3: attr_accessor :name
4:
5: def initialize(name = :test)
6: @name = name
7: yield self if block_given?
8: define
9: end
10:
11: def define
12: task name do
13: puts 'I Run Second'
14: end
15: end
16:
17: end
18:
19: FooTask.new :foo => [:bar] do
20: end
21:
22: task :bar do
23: puts 'I Run First'
24: end
</div> </div>
The result of running ‘rake foo’ on this code, is this:
As you can see, the dependency task of ‘:bar’ is executed first, as expected.
Considering everything that I’ve been learning about ruby in the last few days, I have to say that this feels more like the ruby way of coding. It is far less explicit, reduced code, still as functional, and has the syntax of a standard ‘task :foo => :bar do’ call that most rake users are familiar with.