Err on the side of learning

Rake: Rule Tasks

At one point, I thought about writing about something else besides Rake (Rails 4.1 perhaps?). But, with the recent passing of Jim Weirich, I felt it better to continue showcasing one of his many contributions to the Ruby community.

So, to that end, in this post we’re going to look at another capability of Rake: rule tasks. We’ll cover how create them, how they work, and then we’ll expand on the example from the previous post to make it usable for more of our configuration files.

Rule Tasks

Rule tasks, also known as synthesized tasks, have the same characteristics as all other kinds of tasks: they have a name, they can have zero or more actions, they can have prerequisites, and if Rake determines the task needs to be run it will only be run once.

What makes rule tasks different is that you don’t actually give them a name – I know, I just said that rule tasks have names, just bear with me – instead when you declare the task you give it a pattern in place of a name.

Task Declaration

If that made no sense, hopefully looking at some code will clear things up. First, we declare the rule task, and for that we use the rule method:

rule/foo/do|task|puts'called task named: %s'%task.nameend

In the above example, we used a Regexp pattern to create a rule task that will match any task name with foo in it, and it’s action will report the task’s name. Let’s see it in action:

$ rake foobar
called task named: foobar

As you can see above, once executed, the task’s name was foobar, as that was the name given to the rake command, but the rule’s pattern is /foo/.

A common use for rule tasks is when dealing with files, especially when we don’t necessarily know what the file’s name will be, but we know what to do based on part of the file’s name, like its extension:

In the above example, we used a Regexp pattern to create a rule task that will match any task name ending in .txt, and it’s action will create a file with that name. Let’s see how this task works in action:

This approach of matching based on the end of the task’s name is so common in Rake, we actually don’t need to use a Regexp for it, as just a String of what the end of the task’s name will be will suffice:

Dependencies

As with any other kind of Rake task, rule tasks can have dependencies. These dependency tasks can be either regular, file, or other rule tasks. And, they are declared using the same Hash syntax we’ve seen before:

Rules for Files

Rule tasks don’t need to be about files, as some of the examples above have shown, but if there is a file with the same name as the task’s name, then that task will have the characteristics of a file task. There’s an entire post in this series about file tasks, if you need a reminder of their characteristics and how they are used. But, in a gist, it means: the task will only be executed if the file does not exist, or unless it has a file task dependency with a newer timestamp than itself. Also like file tasks, if the dependency is a rule task matching existing files, you do not need an explicit declaration for the dependency task itself.