Prasanna Natarajan

Rake notes

These notes were taken while watching Avdi’s Rubytapas, which is an excellent guide for any programmer.

Rake command line flags

# display all tasks
$ rake -T

# show with prerequisites
$ rake -P
rake default
rake html

# show task definition location
$ rake -W grape:clear_tokens
rake grape:clear_tokens
/Users/prasanna/src/re/qzick-app/qzick/lib/tasks/grape/clear_token.rake:4:in `block in <top (required)>'

More flags.

# show trace. But before that, in your rakefile, set this option:
# Rake.application.options.trace_rules = true

$ rake my_task --trace

# run tasks parallely
$rake -m
# or define task in Rakefile as `multitask`

File tasks

A file task is a task named after any file. Eg:

task html: ['ch1.html', 'ch2.html', 'ch3.html']

The html task above, looks like it depends on the existence of 4 files. So to finish the html task, rake will try to look for:

file 'ch1.html' => '' do
 # u need to build the file here

Another file task example.

I want to create a html file based on a markdown file. But I want to do it efficiently. I only need to rebuild the .html file if the corresponding .md file has changed since last time.

%w( do |md_file|
  html_file = File.basename(md_file, '.md') + '.html'
  file html_file => md_file do
    sh "pandoc -o #{html_file} #{md_file}"

Invoking the rake task:

$ rake ch1.html   #(not

Rake determines that a file task needs to be run only if the file doesn’t exist or if any of the prerequisite file tasks are newer.

Here’s another example. To create a new database.yml file based on database.yml.example file.

file 'config/database.yml' => 'config/database.yml.example' do
  cp 'config/database.yml.example', 'config/database.yml'

We could refactor this. Instead of duplicating the filename strings inside the block, use the block parameter ’t’ to get hold of them.

file 'config/database.yml' => 'config/database.yml.example' do |task|
  cp task.prerequisites.first,

And run the task like:

$ rake config/database.yml

What if there are other *.example files that you need to copy? There’s the rule task for that.

Rule task

rule '.yml' => '.yml.example' do |task|
  cp task.source,

Run the task with:

$ rake config/database.yml

Rake FileList

What does Rake::FileList actually return? How exclude and ext methods on a filelist works?

# returns an array
files = '**/*.md', '**/*.markdown'
# ["content/pages/", "content/pages/", "README.markdown", "content/pages/now.markdown"]

files.exclude /markdown/
# ["content/pages/", "content/pages/"]

# ext is a monkey patched method on String
files.ext '.MARKDOWN'
# ["content/pages/about.MARKDOWN", "content/pages/habit.MARKDOWN"]

Rake pathmap

source_files = 'sources/**/*.md'
# ['sources/', 'sources/subdir/', 'sources/', 'sources/']

This filelist must be converted to html files that have outputs dir instead of sources dir. How?

output_files = source_files.pathmap "%{^sources/,outputs/}X.html"
# ['outputs/a.html', 'outputs/subdir/b.html', 'outputs/c.html', 'outputs/d.html']