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:

image

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.

A Failed Opportunity To Coach, Teach, And Help Others Improve