所以我有一个rake文件,如下所示:
require 'fileutils'
task :copy do
FileUtils.cp_r 'src', 'target'
end
我怎么能:
:copy
任务依赖于src
目录,以便只在需要时启动它? :copy => 'src'
和:copy => FileList['src/*'].to_a
似乎无效。我可以照顾这样的第一个问题:
task :copy do
sh 'rsync -ru src/* target'
end
我想,如果合理的可能,只用红宝石/耙子做这件事。这也有些负责第二个问题,因为如果没有文件发生变化,rsync
将不会做任何事情,但我希望rake任务在可能的情况下根本不执行。< / p>
答案 0 :(得分:3)
为了避免执行任务,Rake需要知道目标和源以及用于确定是否执行任务的规则,以便从源创建目标。
通常,规则是“时间修改”,即如果源比目标更新,则Rake将运行任务。您可以通过提供Proc作为源依赖项来修改它。请参阅“高级规则”下的http://docs.rubyrake.org/user_guide/chapter03.html(但需要进行一些实验才能了解正在发生的事情!)。
所以你的任务必须取决于目标。如果你知道目标不存在,那应该很容易:
task :copy => 'target/' do
sh 'rsync -ru src/ target' # trailing slash is significant; target will be created
done
如果目标已存在,则会变得更加复杂。您可以为每个文件定义一个规则,但坦率地说,我只是运行rsync并完成它。 Rsync在本地文件系统上非常快,每次运行它都没什么大不了的。
答案 1 :(得分:0)
这是一个OS独立且纯Ruby的解决方案
class File
def self.update(src, dst)
if File.exist? dst
# skip if src file modification or creation time is same or earlier than target
return if [File.ctime(src), File.mtime(src)].max <= [File.ctime(dst), File.mtime(dst)].max
else
# create target folder if not present
FileUtils.mkdir_p(File.dirname(dst)) unless File.exist? File.dirname(dst)
end
FileUtils.cp(src, dst)
puts src
rescue => e
puts "#{e}\n#{e.backtrace}"
end
end
File.update source_file, target_file