Rake Tasks, Arguments and Default Values

Jim Weirich was awesome.I had a discussion with a coworker today where he openly asked if rake tasks can take arguments… and if they can, can the task’s arguments have default values set.

Passing defaulted arguments to a rake task is actually super easy and I can definitely empathize with people who ask have no idea this is possible.  If you look over a typical unparameterized rake file the DSL looks SORTA like methods but sorta not and it can be a little confusing. This post aims to serve as an example of how to pass arguments to your rake tasks and more importantly, how to set default values.

Here’s an example rake task with sole purpose of yelling your arguments into your face:

namespace :arg_yellifier do
  desc 'Yells your argument directly into your face'
  task :yell, [:phrase] do |t, args|
    args.with_defaults(phrase: "don't tell anyone but... yolo")
    puts args[:phrase].upcase + '!'
  end
end

The way you call :yell is like this:

➜ projects rake arg_yellifier:yell[quietness]
QUIETNESS!

As you can see, this task takes in an argument called `:phrase` that is set to the value of “quietness” then uppercases it and finally adds a bang to the end.

When you use a block in conjunction with `task` it exposes two variables. The first, which I’ve called `t`, is the task object and the second, `args` is set of arguments passed in by the user.  For this rake task args has one item named `:phrase` and it can be accessed via `args.phrase` or `args[:phrase]`.

The interesting thing here is that `args` is not some kind of hybrid hash. It’s actually an instance of the Rake::TaskArguments class. This is awesome because we can call methods on it such as `with_defaults`.  `with_defaults` simply takes a list of key: value pairs where the key is the arg name and the value is it’s default value.

Check it out in action:

➜ projects rake arg_yellifier:yell
DON'T TELL ANYONE BUT... YOLO!

 

Dear Users of zsh:

If you’re calling rake tasks with arguments and have problems running rake tasks with arguments… such as..

➜ projects rake arg_yellifier:yell[quietness]
zsh: no matches found: arg_yellifier:yell[quietness]

You need to escape the `[` and `]` like this:

➜ projects rake arg_yellifier:yell\[muhahahah\]
MUHAHAHAH!