18

Is there a straight forward way to modify a Rake task to run some bit of code before running the existing task? I'm looking for something equivalent to enhance, that runs at the beginning rather than the end of the task.

Rake::Task['lame'].enhance(['i_run_afterwards_ha_ha'])
bigtunacan
  • 4,873
  • 8
  • 40
  • 73
  • The task has to be called `lame`, it can't be called `not_so_lame` and just run some code before invoking `lame`? `Rake::Task["lame"].invoke` – Kris Mar 29 '13 at 17:25
  • I must not understand something in your response? What are you implying that it "has to be called lame, it can't be called not_so_lame"? – bigtunacan Mar 29 '13 at 19:04

2 Answers2

39

You can use the dependency of Rake task to do that, and the fact that Rake allows you to redefine existing task.

Rakefile

task :your_task do
  puts 'your_task'
end
task :before do
  puts "before"
end
task :your_task => :before

As result

$ rake your_task
before
your_task
toch
  • 3,905
  • 2
  • 25
  • 34
  • I tried the syntax above and that did not work for me. And I thought enhance could be setup in such a manner as to run something either before or after a task. I wasn't having luck with that either. Further digging into the existing task I was wanting to prefix my custom behavior onto and I realized it was already setup as a dependency :visable_task => :undercover when I was then trying to prefix my behavior to the :visable_task => :my_deps this was running at the end. By instead setting up my dependency as :undercover => :my_deps everything worked as I had expected. – bigtunacan Mar 29 '13 at 19:02
  • 1
    I've accepted your answer though as it is certainly right; and next time I'll do some further digging on my end! Thanks! – bigtunacan Mar 29 '13 at 19:02
  • 1
    You should define a new task and then add it as a prerequisite, passing your task full name as the first argument to .enhance(). See here for a detailed explanation http://www.dan-manges.com/blog/modifying-rake-tasks :-) – vjt Mar 14 '14 at 19:39
  • Note that this does not work exactly as you suppose. You should check the flow with `-n` dry-run rake flag that prints the order. In my case I wanted to put a thing before the `rake release` but it appeared to consist of several tasks and my hook was placed in the middle. Instead I had to prepend the `build` task -- this is not obvious and would work incorrectly if I wasn't enough attentive to check the dry-run. Maybe it's because those subtasks are already attached to `release` in the same way, idk. – Nakilon May 05 '18 at 06:53
8

Or you could use the rake-hooks gem to do before and after hooks:

https://github.com/guillermo/rake-hooks

namespace :greetings do 
    task :hola    do puts "Hola!" end ;
    task :bonjour do puts "Bonjour!" end ;
    task :gday    do puts "G'day!" end ;  
end 

before "greetings:hola", "greetings:bonjour", "greetings:gday" do
  puts "Hello!"
end

rake greetings:hola # => "Hello! Hola!" 
Chris Lewis
  • 1,315
  • 10
  • 25