Tuesday, May 3, 2011

How to run Rake tasks from within Rake tasks?

I have a Rakefile that compiles the project in two ways, according to the global variable $build_type, which can be :debug or :release (the results go in separate directories):

task :build => [:some_other_tasks] do
end

I wish to create a task that compiles the project with both configurations in turn, something like this:

task :build_all do
  [ :debug, :release ].each do |t|
    $build_type = t
    # call task :build with all the tasks it depends on (?)
  end
end

Is there a way to call a task as if it were a method? Or how can I achieve anything similar?

From stackoverflow
  • task :build_all do
      [ :debug, :release ].each do |t|
        $build_type = t
        Rake::Task["build"].execute
      end
    end
    
  • for example:

    Rake::Task["db:migrate"].invoke

  • task :build_all do
      [ :debug, :release ].each do |t|
        $build_type = t
        Rake::Task["build"].reenable
        Rake::Task["build"].invoke
      end
    end
    

    That should sort you out, just needed the same thing myself.

    Mr Rogers : Thanks. Just what I was looking for.
    kch : This is functional, but way too verbose. Sure there's nothing better?
    csexton : Exactly what was needed -- thanks.
  • If you need the task to behave as a method, how about using an actual method?

    task :build => [:some_other_tasks] do
      build
    end
    
    task :build_all do
      [:debug, :release].each { |t| build t }
    end
    
    def build(type = :debug)
      # ...
    end
    

    If you'd rather stick to rake's idioms, here are your possibilities, compiled from past answers:

    • This always executes the task, but it doesn't execute its dependencies:

      Rake::Task["build"].execute
      
    • This one executes the dependencies, but it only executes the task if it has not already been invoked:

      Rake::Task["build"].invoke
      
    • This first resets the task's already_invoked state, allowing the task to then be executed again, dependencies and all:

      Rake::Task["build"].reenable
      Rake::Task["build"].invoke
      

      (Notice that dependencies already invoked are not re-executed)

0 comments:

Post a Comment