Rake::Task Multiple Invokes

During my early development of apps, I find myself running the same three rake tasks over and over. So I though I would create a custom rake task so that I can execute all three with one command. Plus, when you invoke rake tasks, it only loads the framework once, hence it is much faster.

Except that you can not invoke more that once per rake execution. So this does not work, it only invokes the first 'Rake::Task':

namespace :db do   desc "Rebuild Development Db, Clone to Test"   task :rebuild_all do     puts "Development Db to VERSION=0"     ENV['VERSION'] = '0'     Rake::Task["db:migrate"].invoke     ENV.delete 'VERSION'

    puts "Development Db Migrate to Current"     Rake::Task["db:migrate"]. invoke

    puts "Development Db Clone to Test"     Rake::Task["db:test:clone"]. invoke   end end

I've been all over the place trying to find a workaround. Any ideas?

I'm not a rake expert, but how about:

  task :rebuild_db do     sh "rake db:migrate VERSION=0"     sh "rake db:migrate"   end

  task :rebuild_all => %w(rebuild_db db:test:clone)

Try using Rake’s dependency mapping:

task :migrate_env_zero do ENV[“VERSION”] = 0 end

task :migrate_env do ENV[“VERSION”] = nil end

task :migrate_down => [:migrate_env_zero, “db:migrate”]

task :migrate_up => [:migrate_env, “db:migrate”]

desc “Rebuild all” task :rebuild_all => [“migrate_down”, “migrate_up”, “db:test:clone”]

I did just write that by memory, you’ll have to give it a try, but it should work.

Jason

That is what I originally had, and it does work. But because you are essentially executing each task sequentially, each task has to load the entire environment. AKA, it's slow.

I'm trying to speed it up by loading the environment only once and then executing the tasks.

Thanks.

Well, in that case you'll need to dig into the db:migrate task and perform its operation directly (it's quite simple actually).

Why are you migrating all the way back to version 0 and then all the way back up? Why not take a snapshot of the database after the migration and just reload that snapshot using tools for your db?

You still only get one run of db:migrate with that.

Thanks Jason, but... Sorry, doesn't work. The first time it runs, in only executed the "rake db:migrate VERSION = 0", then nothing else. Subsequent runs do nothing.

Anyone else?

Well, in that case you'll need to dig into the db:migrate task and perform its operation directly (it's quite simple actually).

I though I could just add to it with a

Why are you migrating all the way back to version 0 and then all the way back up? Why not take a snapshot of the database after the migration and just reload that snapshot using tools for your db?

Because I'm adding fields, renaming fields, changing their def. I'm not at the point of playing with data yet. Sure, I could add new migrations every time I change the name of a fields. But I don't want dozens of migrations files for such small changes. Yes, later on in development I will add migrations. But for now, and for me, it's just easer to correct the mistake, tear it down, and rebuild it.

I didn't want to re-invent the wheel, so to speak. And, I don't have dba tools normally running, at least not in this phase of dev.

I looked at the databases.rake to see exactly what is going on, but even those call invoke. Sure, I could extract out each task's commands and build my own. But this was supposed to be quick and easy.

Looks like I'll just have to live with a few extra keystrokes for a while.

Thanks.

Yeah, I forgot that Rake still only executes any given task just once per run no matter how many times it’s called.

I think you’re best bet is to write an external script. I don’t think this is possible through Rake.

Jason