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
Instance and Class Variables in Rails Controller
Best Way to Generate Order Numbers for an Online Store
Postgresql Gem Pg Was Unable to Install
Best Practice About Empty Belongs_To Association
Using Ruby's Optionparser to Parse Sub-Commands
Why Are Symbols Not Frozen Strings
Error When Starting Rails Server: Warning: Insecure World Writable Dir /Usr in Path, Mode 040777
Why Should I Use Rspec or Shoulda with Rails
Which Ruby Gems Support the Facebook API
How to Create a Rest API for a Ruby Application
Ruby Koan 151 Raising Exceptions
Ruby Concatenate Strings and Add Spaces
What Alternatives to Irb Are There