tags:

views:

194

answers:

5

I'm new to Rake and using it to build .net projects. What I'm interested in is having a Summary task that prints out a summary of what has been done. I want this task to always be called, no matter what tasks rake was invoked with.

Is there an easy way to accomplish this?

Thanks


Update on the question, responding to Patrick's answer what I want is the after task to run once after all other tasks, so the output I want is:

task :test1 do 
  puts 'test1'
end

task :test2 do 
  puts 'test2'
end

Rake::Task.tasks.each do |t|
    <Insert rake magic here>
#  t.enhance do 
#    puts 'after'
#  end
end

$ rake test1
test1
after

$rake test2
test2
after

$rake test1 test2  
test1
test2
after

and if

task :test3 =>[:test1, :test2]
   puts 'test3'
end

    $rake test3
test1
test2
test3
after

Even though the bounty is gone, any further help much appreciated. (Sadily I don't think that I can offer another bounty.)

A: 

Sounds like you are looking for an after_filter, like rails uses. Take a look at actionpack/lib/action_controller/filters.rb in Rails for a sample implementation you could try to adapt. Since a rake file is just ruby, you could include your version in your top level rakefile, and set an :after filter on all tasks.

Jeff Paquette
hmmmm. I'm hoping not to have to learn that much rails/ruby to get this done in the short term. :(
rathkopf
A: 

I don't know if it's the best way but it's the simpler:

Make all your "public tasks" Summary ones that call real tasks.

task :compile => :realcompile do
   summary stuff
end
Nikkau
+1  A: 

You should be able to do this with 'enhance':

Rake::Task["my_task"].enhance do
  Rake::Task["my_after_task"].invoke
end

This will cause 'my_after_task' to be invoked after 'my_task'.

If you want to apply this to all tasks, just loop over all the tasks and call enhance for each:

Rake::Task.tasks.each do |t| 
  t.enhance do 
    Rake::Task["my_after_task"].invoke
  end
end

Full test file:

task :test1 do 
  puts 'test1'
end

task :test2 do 
  puts 'test2'
end

Rake::Task.tasks.each do |t|
  t.enhance do 
    puts 'after'
  end
end

And the output:

$ rake test1
test1
after

$ rake test2
test2
after
Patrick Ritchie
Thanks. I'm afraid I didn't state my question clearly. I want the after task to run once, after other tasks are complete.So: $ rake test1 test2 would outputtest1test2after$rake test1test1after$rake test2test2afterAny idea how to make that happen?
rathkopf
Ah ok, found a solution for you. Less elegant but it works. If you're interested I can explain in detail what I'm doing to get this to work...
Patrick Ritchie
+1  A: 

Posting this as a new answer to keep the other one available. This is much less elegant as I have to get into the guts of Rake and manually update the task list, but it works.

task :test1 do
  puts 'test1'
end

task :test2 do 
  puts 'test2'
end

task :after do
  puts 'after'
end

# top_level_tasks is't writable so we need to do this ugly
# instance_variable_set hack...
current_tasks =  Rake.application.top_level_tasks
current_tasks << :after
Rake.application.instance_variable_set(:@top_level_tasks, current_tasks)

Outputs:

$ rake test1
test1
after

$ rake test1 test2
test1
test2
after
Patrick Ritchie
GREAT! This is exactly what I want. I would love to know what magic is going on here. Can you give me more of an explination of what's happening? In the mean time, I'll see what I can find on google.
rathkopf
OK. I understand what's going on. Nice work. Thanks.
rathkopf
Sure. As an aside, I'm at a conference and tracked down Jim Weirich (the author of rake) to see if this wis the best way to solve the problem. His answer was that Rake doesn't have a built in way to do this, but he's open to a patch if someone can come up with a generalized method for doing it.So the code: The Rake application has a reader to keep track of the tasks to run called 'top_level_tasks'. Because it's read only we need to read it out, update it and then use instance_variable_set to push the change back into the application. If it was read write we could to it all in one line.
Patrick Ritchie
+3  A: 

Apart from the ugly Rake.application.instance_variable_set, you can enhance the last task on the command-line like so:

  last_task = Rake.application.top_level_tasks.last
  Rake::Task[last_task].enhance do
    puts 'after'
  end

That should do exactly what you need to do!

awendt
You have one `end` at the end that shouldn't be there, I guess.
Konstantin Haase
Thanks, Konstantin! I corrected it.
awendt
Interesting. The accepted solution below is working, and I haven't had to modify the script for ages, but next time I do I'll look at using this method. It is definitely more elegant.
rathkopf