CodeGnome Consulting, LTD

Programming - DevOps - Project Management - Information Security

Rails Note Tasks

| Comments

Even if you work with Ruby on Rails every single day, it’s a large framework with a lot of dark corners. Today, we shine some light on one of those under-utilized dark corners: the rake notes task.

The Notes Task

The notes task is definitely documented, but it’s easy to overlook. By default, this task will find comments that start with one of the following keywords:

  • FIXME
  • OPTIMIZE
  • TODO

The notes task is also limited to files with the following extensions:

  • .builder
  • .erb
  • .haml
  • .rb
  • .slim

For example, running rake notes on a sample project will search the code base and report the following notes:

rake notes
1
2
3
4
5
$ rake notes
lib/example.rb:
  * [  5] [FIXME] This is something I ought to fix.
  * [ 15] [TODO] Refactor #hello_world into #goodbye_world.
  * [ 23] [OPTIMIZE] Do something clever here.

Each list starts with the relative path from Rails.root to the file where the tag was found. Each list item includes the line number of the note, the note type, and the portion of the note that shares the line with the note tag.

Keep that last bit firmly in mind: long notes that wrap across lines will not show the whole note. Tagged notes should therefore be summaries of comments to follow, rather than dissertations.

Tagging Notes in the Source Code

Note tagging has some definite limitations besides length. For example, the following line will be found by the default notes task:

# FIXME: This is something I ought to fix.

but this line will not:

# URGENT: FIXME: This is something I ought to fix.

Also, it’s worth nothing that the notes task accepts an optional trailing colon, which is stripped off when displaying output. Using other characters as separators will result in odd-looking output. For example, consider this sample source file:

lib/formatting_example.rb
1
2
3
4
# FIXME: This is something I ought to fix.
# FIXME - This is something I ought to fix.
# FIXME--This is something I ought to fix.
# FIXME  This is something I ought to fix.

Now compare the output of rake notes, paying careful attention to the characters it strips out, and the ones it leaves in. Also note that it ignores spaces between the note tag and the note text.

Output of Notes Task
1
2
3
4
5
6
$ rake notes
lib/formatting_example.rb:
  * [  1] [FIXME] This is something I ought to fix.
  * [  2] [FIXME] - This is something I ought to fix.
  * [  3] [FIXME] --This is something I ought to fix.
  * [  4] [FIXME] This is something I ought to fix.

The lesson here is to use colons if you want, but don’t use other characters (such as dashes) as separators between the note tag and the note text.

Finding Only Certain Notes

You can limit the search to specific types of notes (i.e. FIXME or TODO) by adding the note type to the task name. For example:

  • rake notes:fixme
  • rake notes:todo

It is worth nothing that when you do this, the task will no longer display the note type. For example:

notes:fixme
1
2
3
$ rake notes:fixme
lib/example.rb:
  * [  5] This is something I ought to fix.

You can also find custom notes. For example, XXX is a common note tag for dangerous or tricky code. Let’s invoke a custom notes search for the XXX tag like this one:

# XXX: Danger, Will Robinson!

notes:custom
1
2
3
$ rake notes:custom ANNOTATION=XXX
lib/example.rb:
  * [ 20] Danger, Will Robinson!

This is still somewhat intuitive, since you’re asking for only one type of note at a time, but this breaks badly if you ask for more than one custom note type. For example, consider this custom annotation that uses regular expression alternation to find all the tags we know about.

Custom Annotations with Regular Expressions
1
2
3
4
5
6
$ rake notes:custom ANNOTATION="FIXME|OPTIMIZE|TODO|XXX"
lib/example.rb:
  * [  5] This is something I ought to fix.
  * [ 15] Refactor #hello_world into #goodbye_world.
  * [ 20] Danger, Will Robinson!
  * [ 23] Do something clever here.

It found all the tags we asked for, but the output doesn’t identify which tag is associated with each note. On the plus side, it’s nice to be able to search for multiple annotations at once, but the inability to separate them out visually when you do is irksome, especially if you have a Rails code base that requires a long time to load and you want to avoid looping over rake invocations to separate your note tags.

Speed vs. Portability

Ack or grep are generally faster and more flexible tools for finding tagged comments in your code. There’s no reason you can’t simply use them instead, if you are comfortable with them.

Ubuntu ack-grep Example
1
2
3
4
$ ack-grep 'FIXME|TODO'
lib/example.rb
5:# FIXME: This is something I ought to fix.
15:# TODO: Refactor #hello_world into #goodbye_world.

However, since the built-in rake note tasks are portable and built-in, and the screen output is nicely-formatted, it’s good to know that Rails includes this functionality out of the box. By standardizing on the task-supported tags, you also benefit from the Rails “convention over configuration” philosophy and ensure that you’re seeing the same output as your fellow coders, regardless of whether they’re running Linux, OS X, or Windows.

Give rake notes a try. Even if you decide not to use it, knowing which batteries are included with your Rails application is always a good thing.

Comments