Overriding existing Rake tasks

I added some long-running integration tests to a Rails application today and quickly began getting irritated that issuing the rake command runs all tests… unit, functional, AND integration. Since I run rake quite frequently, any sizable delay can quickly get annoying.

The task that gets executed by rake is the :test task. After spending a few minutes trying to replace it, I discovered that there isn’t an immediately obvious way to override an existing task in Rake. After jumping through a few hoops, though, I did manage to do it.

First, here’s my replacement for the existing :test task:

task :test do
  Rake::Task["test:units"].invoke rescue got_error = true
  Rake::Task["test:functionals"].invoke rescue got_error = true
  raise "Test failures" if got_error
end

All it does is run the unit and functional tests, but no integration tests. I stuck this in my Rakefile right after the require 'tasks/rails' line. Next up, I reopened the Rake::TaskManager module to create my own little helper method to remove a task:

Rake::TaskManager.class_eval do
  def remove_task(task_name)
    @tasks.delete(task_name.to_s)
  end
end

Lastly, I called this method from another method defined inside my Rakefile. This way, I could use syntax like remove_task :test which would fit with my other task definitions in the file. This is how everything looks put together (remember that this code should be inserted immediately after the require 'tasks/rails' line or it won’t work):

Rake::TaskManager.class_eval do
  def remove_task(task_name)
    @tasks.delete(task_name.to_s)
  end
end

def remove_task(task_name)
  Rake.application.remove_task(task_name)
end

# Override existing test task to prevent integrations
# from being run unless specifically asked for
remove_task :test
task :test do
  Rake::Task["test:units"].invoke rescue got_error = true
  Rake::Task["test:functionals"].invoke rescue got_error = true
  raise "Test failures" if got_error
end

This did the trick for me, but it’s kind of long. Anyone know a better way of doing it?

Rails, Ruby, Tutorials

3 thoughts on “Overriding existing Rake tasks

  1. Thanks for the idea! I’ve decided to go further and made a plugin that allows to override Rake tasks in a prettier way (at list I think so :)), but the idea is the same.

  2. Pingback: Rake Hacks: Overriding Tasks, Quick Binary Run, and Intelligent IRB / procedural is matthew hawthorne

  3. Pingback: Foliosus :: Blog Archive :: HOWTO monkeypatch Rake: overriding a Rake task

Comments are closed.