2012-04-26 22 views
2

所以我有一个耙文件类似如下:耙 - 仅复制更改的文件

require 'fileutils' 

task :copy do 
    FileUtils.cp_r 'src', 'target' 
end 

如何我:

  1. 只复制已更改的文件?
  2. 使:copy任务对src目录具有依赖性,以便仅在需要时启动该目录? :copy => 'src':copy => FileList['src/*'].to_a似乎不起作用。

我可以照顾的第一个问题是这样的:

task :copy do 
    sh 'rsync -ru src/* target' 
end 

我想,如果合理可行,只有红宝石/耙做到这一点。这也有点照顾第二个问题,因为rsync不会做任何事情,如果没有文件已经改变,但我希望耙子任务,如果可能的话,根本不执行。

回答

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在本地文件系统上速度非常快,每次运行它都没什么大不了的。

+0

似乎rubyrake.org不再有耙文件;我相信正确的链接是:http://www.virtuouscode.com/2014/04/23/rake-part-3-rules/(来自https://ruby.github.io/rake/)。 – 2017-10-03 15:52:24

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