我如何在Ruby脚本中运行Rake任务?

我有一个带有Rake任务的 Rakefile ,我通常会从命令行调用它:

rake blog:post Title

我想编写一个Ruby脚本多次调用Rake任务,但我看到的唯一解决方案是使用``(反引号)或 system 进行脱壳。

什么是正确的方法来做到这一点?

0

4 答案

在加载Rails的脚本中(例如 rails runner script.rb

def rake(*tasks)
  tasks.each do |task|
    Rake.application[task].tap(&:invoke).tap(&:reenable)
  end
end

rake('db:migrate', 'cache:clear', 'cache:warmup')
0
额外

这适用于Rake版本10.0.3:

require 'rake'
app = Rake.application
app.init
# do this as many times as needed
app.add_import 'some/other/file.rake'
# this loads the Rakefile and other imports
app.load_rakefile

app['sometask'].invoke

正如Knut所说,如果您想要多次调用,请使用 reenable

0
额外
Hi @JasonFB,你可以通过 app.add_import“#{Gem :: Specification.find_by_name('statesman')。gem_dir} / lib&zwnj; /tasks/statesman.rak‌ e”< /代码>
额外 作者 spikeheap,
这对于宝石内部的任务不起作用
额外 作者 Jason FB,

您可以使用 invokereenable 来第二次执行任务。

你的示例调用 rake blog:post Title 似乎有一个参数。该参数可以用作 invoke 中的参数:

例:

require 'rake'
task 'mytask', :title do |tsk, args|
  p "called #{tsk} (#{args[:title]})"
end



Rake.application['mytask'].invoke('one')
Rake.application['mytask'].reenable
Rake.application['mytask'].invoke('two')

请将 mytask 替换为 blog:post ,而不是要求的任务定义您的rakefile。

该解决方案将结果写入标准输出 - 但您没有提到,您想要抑制输出。


有趣的实验:

您也可以在任务定义内调用 reenable 。这允许任务重新启用自己。

例:

require 'rake'
task 'mytask', :title do |tsk, args|
  p "called #{tsk} (#{args[:title]})"
  tsk.reenable  #<-- HERE
end

Rake.application['mytask'].invoke('one')
Rake.application['mytask'].invoke('two')

结果(使用rake 10.4.2测试):

"called mytask (one)"
"called mytask (two)"
0
额外
@JasonFB你有一个例子,为什么不呢?
额外 作者 knut,
@JasonFB另请参阅我编辑的答案。也许这是你的问题的替代方案..
额外 作者 knut,
这对于宝石内部的任务不起作用
额外 作者 Jason FB,

timocracy.com

require 'rake'
require 'rake/rdoctask'
require 'rake/testtask'
require 'tasks/rails'

def capture_stdout
  s = StringIO.new
  oldstdout = $stdout
  $stdout = s
  yield
  s.string
ensure
  $stdout = oldstdout
end

Rake.application.rake_require '../../lib/tasks/metric_fetcher'
results = capture_stdout {Rake.application['metric_fetcher'].invoke}
0
额外
对于改变stdout,我建议通过 #dup ,然后将 #reopen 保存到一个 Tempfile ,然后重新打开原始文件。如果任务使用 STDOUT 常量或者运行一个外部程序,仅仅分配 $ stdout 将不起作用。
额外 作者 Kelvin,
使用Rails 3.1时,rake / rdoctask已被弃用,任务/导轨丢失。只需要第一条要求声明,上述工作就可以完成。
额外 作者 jwadsack,
请注意, rake_require 总是将给定路径与来自 $ LOAD_PATH 数组的每个路径连接起来,并检查文件的存在。所以第一个参数应该是相对路径。即使它包含前导斜杠(或非Unix系统上的反斜杠),它也会被视为相对。
额外 作者 siefca,