How to Make a Rake Task Run After All Other Tasks? (I.E. a Rake Afterbuild Task)

How do I make a Rake Task run after all other tasks? (i.e. a Rake AfterBuild task)

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

Run one rake task after another completes

You can use enhance to extend one task with other:

task :extra_behavior do
# extra
end

Rake::Task["first:task"].enhance do
Rake::Task[:extra_behavior].invoke
end
  • Reference
  • Reference

Run all rake tasks?

Here's one way:

namespace :hot_tasks do |hot_tasks_namespace|
task :task1 do
puts 1
end
task :task2 do
puts 2
end
task :all do
hot_tasks_namespace.tasks.each do |task|
Rake::Task[task].invoke
end
end
end

running it:

# bundle exec rake hot_tasks:all
1
2

More (not necessarily better) ideas at this question, especially if you're in a rails app.

How do I execute a rake task after every db:reset

In my opinion, the best way is to create your own rake task calling all the tasks needed (to avoid changing Rails/Rake basic tasks):

# lib/tasks/reset_and_create
namespace :database do
desc 'Reset the database to a fresh and clean DB ready for use'
task :reset_and_create do
Rake::Task['db:reset'].invoke
Rake::Task['newsworker:create'].invoke
# if you need to pass arguments to your tasks, use:
# Rake::Task['your_task'].invoke(your_arg, another_arg)
end
end

And use it like this:

rake database:reset_and_create

Rails app Rake task doesn't know how to build other Rake task

In general, your solution should work:

require 'rake'

task :environment do
puts 'task environment'
end

namespace :robots do
task :update_robots do
puts "task robots:update_robots"
end
end

task cron: :environment do
puts 'task cron'
Rake::Task['robots:update_robots'].reenable
Rake::Task['robots:update_robots'].invoke
end

Rake::Task['robots:update_robots'].invoke
Rake::Task[:cron].invoke

# >> robots:update_robots was invoked
# >> task robots:update_robots
# >> task environment
# >> task cron
# >> task robots:update_robots

My first thought is that you must have the rake task wrong (are you sure it's "robots:update_robots" ?)

It's unusual to me that you need to reenable it, this implies that what you want is not Rake, but just plain old Ruby. Move the contents of the update_robots task out to a method which you can then invoke directly instead of trying to treat tasks like methods (tasks are for handling dependencies, they only invoke once on purpose, and your need to bend them around that implies you're using the wrong tool for the job). Then, both your code and the robots:update_robots can just call the same method:

require 'rake'

def update_robots
puts "method update_robots"
end

task :environment do
puts 'task environment'
end

namespace :robots do
task :update_robots do
update_robots
puts "task robots:update_robots"
end
end

task cron: :environment do
puts 'task cron'
update_robots
end

Rake::Task['robots:update_robots'].invoke
Rake::Task[:cron].invoke

# >> method update_robots
# >> task robots:update_robots
# >> task environment
# >> task cron
# >> method update_robots

Can I catch errors and continue to next Rake task?

Rake is just Ruby, so you can use Ruby's error handling feature.

namespace :test do
task :migrate do
begin
Rake::Task['A:migrate'].invoke
rescue => e
log(e)
end
Rake::Task['B:migrate'].invoke
end
end

How to make sure only one rake task is running at a time?

Unix solved this issue with pid files. Pid files are located in /var/run and contain the programs process Id. Here is the man page: http://fuse4bsd.creo.hu/localcgi/man-cgi.cgi?pidfile+3

You might find it a bit old fashioned (and I agree), but it's an often used and proven method.

Rake task: How to make task from another namespace prerequesite?

You could probably do this, but dont know if this is the recommended way:

namespace :import do 
task :products => [:environment, "init:tax_categories"] do
... # create products from import and reference tax categories
end
end

Is there a way to run a rake task without running the prerequisites?

I seem to have solved this problem by simply adding extra tasks in the format "taskname_no_prerequisites". So for example in the code below executing "rake install_no_prerequisites" would not cause "build" to be executed.

desc "Build"
task :build do
puts "BUILDING..."
end

desc "Install"
task :install => :build do
puts "INSTALLING..."
end

Rake::Task::tasks.each do |task|
desc "#{task} without prerequisites"
task "#{task}_no_prerequisites".to_sym do
task.invoke_without_prerequisites
end
end

module Rake
class Task
def invoke_without_prerequisites
execute
end
end
end


Related Topics



Leave a reply



Submit