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

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

问题描述:

我有一个Rakefile用耙子任务,我通常会在命令行称:如何在Ruby脚本中运行Rake任务?

rake blog:post Title 

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

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

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} 
+1

使用Rails 3.1耙/ rdoctask已弃用,任务/导轨丢失。只需要第一条要求声明,上述工作就可以完成。 – jwadsack 2012-01-09 21:07:44

+0

为了改变stdout,我建议通过`#dup`将原始流保存,然后`#reopen`复制到`Tempfile`中,在重新打开原始文件后读取它。如果任务使用STDOUT常量或运行外部程序,仅分配`$ stdout`将不起作用。 – Kelvin 2013-03-06 22:29:06

+0

请注意,`rake_require`总是将给定路径与`$ LOAD_PATH`数组中的每条路径连接起来,并检查是否存在文件。所以第一个参数应该是**相对路径**。即使它包含前导斜杠(或非Unix系统上的反斜杠),它也会被视为相对。 – siefca 2013-12-04 15:55:06

您可以使用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') 

blog:post取代mytask,而是任务定义,你可以require您的Rake文件。

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


有趣的实验:

你可以打电话给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') 

结果(与耙10.4.2测试):

"called mytask (one)" 
"called mytask (two)" 

这适用于耙版本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 

正如克努特所述如果要多次调用,请使用reenable

在使用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')