Thu, 06 Dec 07

Ruby Rake - Invoke vs Execute

First up – I don’t know an awful lot about the magic that is Rake. As such, this is probably common knowledge to most people.

I discovered the difference when trying to execute the db:migrate task from within another rake task (I already knew it worked when declared as a dependency).

# Rakefile
task :foo do
  Rake::Task['db:migrate'].execute
end

#$ rake foo
#=> rake aborted!
#=> uninitialized constant ActiveRecord

I changed Task#execute to Task#invoke and, voila, it all worked fine. The rdoc for those methods is actually pretty self explanatory, having seen the differences in action. Oh well.

I put together a simple example to demonstrate the differences.

# The task (task_1) and its dependency (to_be_run_before_task_1)

task :to_be_run_before_task_1 do
  puts "to_be_run_before_task_1"
end

task :task_1 => ['to_be_run_before_task_1'] do
  puts "task_1"
end

# Three tasks that 'run' task_1

task :invoke_task_1 do
  Rake::Task['task_1'].invoke
end

task :execute_task_1 do
  Rake::Task['task_1'].execute
end

task :run_task_1_using_dependencies => ['task_1']

# 'Running' the tasks

#$ rake task_1
#=> to_be_run_before_task_1
#=> task_1

#$ rake invoke_task_1
#=> to_be_run_before_task_1
#=> task_1

#$ rake execute_task_1
#=> task_1 #*** Note that the dependencies are not run

#$ rake run_task_1_using_dependencies
#=> to_be_run_before_task_1
#=> task_1