in lib/omnibus/file_syncer.rb [90:172]
def sync(source, destination, options = {})
unless File.directory?(source)
raise ArgumentError, "`source' must be a directory, but was a " \
"`#{File.ftype(source)}'! If you just want to sync a file, use " \
"the `copy' method instead."
end
source_files = all_files_under(source, options)
FileUtils.mkdir_p(destination) unless File.directory?(destination)
source_files.each do |source_file|
relative_path = relative_path_for(source_file, source)
parent = File.join(destination, File.dirname(relative_path))
FileUtils.mkdir_p(parent) unless File.directory?(parent)
case File.ftype(source_file).to_sym
when :directory
FileUtils.mkdir_p("#{destination}/#{relative_path}")
when :link
target = File.readlink(source_file)
Dir.chdir(destination) do
FileUtils.ln_sf(target, "#{destination}/#{relative_path}")
end
when :file
source_stat = File.stat(source_file)
if hardlink? source_stat
if existing = hardlink_sources[[source_stat.dev, source_stat.ino]]
FileUtils.ln(existing, "#{destination}/#{relative_path}", force: true)
else
begin
FileUtils.cp(source_file, "#{destination}/#{relative_path}")
rescue Errno::EACCES
FileUtils.cp_r(source_file, "#{destination}/#{relative_path}", remove_destination: true)
end
hardlink_sources.store([source_stat.dev, source_stat.ino], "#{destination}/#{relative_path}")
end
else
begin
FileUtils.cp(source_file, "#{destination}/#{relative_path}")
rescue Errno::EACCES
FileUtils.cp_r(source_file, "#{destination}/#{relative_path}", remove_destination: true)
end
end
else
raise "Unknown file type: `File.ftype(source_file)' at `#{source_file}'!"
end
end
destination_files = glob("#{destination}/**/*")
relative_source_files = source_files.map do |file|
relative_path_for(file, source)
end
relative_destination_files = destination_files.map do |file|
relative_path_for(file, destination)
end
extra_files = relative_destination_files - relative_source_files
extra_files.each do |file|
FileUtils.rm_rf(File.join(destination, file))
end
true
end