具有多个先决条件的 Rake 任务生成多个输出
题
我有一个方法,它依赖于两个文件作为输入,并生成两个或多个文件作为输出。每个输入文件和每个输出文件之间不存在一对一的映射 - 该方法执行组合输入数据的操作以生成各种输出文件。
这是一个(有点做作的)示例:
class Util
def self.perform
`cat source1.txt source2.txt > target1.txt`
`cat source2.txt source1.txt > target2.txt`
end
end
编辑: 我的例子中的实际代码比这复杂得多,并且将生成每个目标文件所完成的工作分成不同的部分是不可行的。于是设立了一个 文件任务 在我的例子中,每个目标文件并不是真正的选择。
如何设置 rake 任务以便在需要时运行此方法一次,即。如果一个或多个目标文件丢失,或者任何源文件比任何目标文件新?
我当前的解决方案如下所示:
task :my_task => ['source1.txt', 'source2.txt'] do |t|
targets = ['target1.txt', 'target2.txt']
if targets.all? { |f| File.exist? f }
mtime_newest_source = t.prerequisites.map {|f| File.mtime(f) }.max
mtime_oldest_target = targets.map {|f| File.mtime(f) }.min
# Stop task early if all targets are up to date
next if mtime_newest_source < mtime_oldest_target
end
# Code that actually produces target files goes here
end
我正在寻找的是定义任务的一种方法,以便除非需要重建目标文件,否则将无法运行其块中的代码。
解决方案
filetasks 是设计的恰好这一点。这是一个好老长解释,这是一个快速的例子:
file 'target1.txt' => ['source1.txt', 'source2.txt'] do
# do something to generate target1.txt
`cat source1.txt source2.txt > target1.txt`
end
file 'target2.txt' => ['source1.txt', 'source2.txt'] do
# again, generate the file
`cat source2.txt source1.txt > target2.txt`
end
.
文件任务可以取决于磁盘上的其他rake任务或文件。如果您的任务取决于文件,则Rake将比较时间戳,如果依赖文件更新,则只运行任务。
更新
这是从两个任务中生成所有目标的工作示例。当第一个创建两个文件时,Rake智能足以跳过第二任务。
def make_the_targets
`cat source1.txt source2.txt > target1.txt`
`cat source2.txt source1.txt > target2.txt`
end
file 'target1.txt' => ['source1.txt', 'source2.txt'] do
puts "making target1.txt"
make_the_targets
end
file 'target2.txt' => ['source1.txt', 'source2.txt'] do
puts "making target2.txt"
make_the_targets
end
task :make_targets => ['target1.txt', 'target2.txt']
. 其他提示
我不相信以上答案是正确的。拉斯的评论
['target1.txt', 'target2.txt'].each {
|target| file target => ['source1.txt', 'source2.txt'] { do_stuff_here }
}
会跑 { do stuff here }
如果耙的话两次 'target1.txt', 'target2.txt'
叫做。
我相信正确解决依赖关系是通过以下方式实现的
file 'target1.txt' => ['source1.txt', 'source2.txt'] { do_stuff_here }
file 'target2.txt' => 'target1.txt'