我有一个方法,它依赖于两个文件作为输入,并生成两个或多个文件作为输出。每个输入文件和每个输出文件之间不存在一对一的映射 - 该方法执行组合输入数据的操作以生成各种输出文件。

这是一个(有点做作的)示例:

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'

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top