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