如何从Rake任务中运行Rake任务?

问题描述 投票:392回答:7

我有一个Rakefile,它根据全局变量$build_type以两种方式编译项目,可以是:debug:release(结果在不同的目录中):

task :build => [:some_other_tasks] do
end

我希望创建一个任务,依次编译项目的两个配置,如下所示:

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

有没有办法将任务称为方法?或者我怎样才能达到类似的效果呢?

ruby rake
7个回答
617
投票

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:

  • 这总是执行任务,但它不执行其依赖项: Rake::Task["build"].execute
  • 这个执行依赖项,但它只在尚未调用的情况下执行任务: Rake::Task["build"].invoke
  • 这首先重置任务的already_invoked状态,然后再次执行任务,依赖项和所有: Rake::Task["build"].reenable Rake::Task["build"].invoke (请注意,已经调用的依赖项不会被重新执行)

117
投票

例如:

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

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

那应该把你排除在外,只需要自己做同样的事情。


11
投票
task :build_all do
  [ :debug, :release ].each do |t|
    $build_type = t
    Rake::Task["build"].execute
  end
end

6
投票
task :invoke_another_task do
  # some code
  Rake::Task["another:task"].invoke
end

3
投票

如果您希望每个任务都运行而不管任何失败,您可以执行以下操作:

task :build_all do
  [:debug, :release].each do |t| 
    ts = 0
    begin  
      Rake::Task["build"].invoke(t)
    rescue
      ts = 1
      next
    ensure
      Rake::Task["build"].reenable # If you need to reenable
    end
    return ts # Return exit code 1 if any failed, 0 if all success
  end
end

-1
投票

我建议不要创建一般的调试和发布任务,如果项目真的是被编译的东西,从而导致文件。您应该使用在您的示例中非常可行的文件任务,如您所述,您的输出将进入不同的目录。假设您的项目只是使用gcc将test.c文件编译为out / debug / test.out和out / release / test.out,您可以像这样设置项目:

WAYS = ['debug', 'release']
FLAGS = {}
FLAGS['debug'] = '-g'
FLAGS['release'] = '-O'
def out_dir(way)
  File.join('out', way)
end
def out_file(way)
  File.join(out_dir(way), 'test.out')
end
WAYS.each do |way|
  desc "create output directory for #{way}"
  directory out_dir(way)

  desc "build in the #{way}-way"
  file out_file(way) => [out_dir(way), 'test.c'] do |t|
    sh "gcc #{FLAGS[way]} -c test.c -o #{t.name}"
  end
end
desc 'build all ways'
task :all => WAYS.map{|way|out_file(way)}

task :default => [:all]

此设置可以使用如下:

rake all # (builds debug and release)
rake debug # (builds only debug)
rake release # (builds only release)

这要求更多,但显示了我的观点:

  1. 必要时创建输出目录。
  2. 只有在需要时才重新编译文件(这个例子只适用于最简单的test.c文件)。
  3. 如果要触发发布版本或调试版本,您可以随时掌握所有任务。
  4. 此示例包含一种定义调试版本和发布版本之间的小差异的方法。
  5. 无需重新启用使用全局变量进行参数化的构建任务,因为现在不同的构建具有不同的任务。构建任务的代码重用是通过重用代码来定义构建任务来完成的。看看循环如何不执行两次相同的任务,而是创建任务,以后可以触发(通过全部任务或在rake命令行上选择其中一个)。
© www.soinside.com 2019 - 2024. All rights reserved.