I have a method that depends on two files for input, and that produces two or more files as output. There is no one-to-one mapping between each input file and each output file - the method performs operations that combines the input data to produce various output files.
Here's a (somewhat contrived) example:
class Util
def self.perform
`cat source1.txt source2.txt > target1.txt`
`cat source2.txt source1.txt > target2.txt`
end
end
Edit: The actual code in my case is much more complicated than this, and it is not viable to separate the work done to produce each target file into distinct parts. Hence setting up one file task per target file is not really an option in my case.
How do I set up a rake task for running this method once when needed and only then, ie. if one or more of the target files are missing, or if any of the source files are newer than any of the target files?
My current solution looks like this:
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
What I am looking for is a way to define the task so that none of the code within its block will be run unless the target files need to be rebuilt.