def cp(sources, target, opts={})
fu_opts = _fileutils_opts
for opt in [:noop, :verbose]
opt = opt.to_sym
fu_opts[opt] = opts[opt] if opts[opt]
end
fu_opts_with_preserve = fu_opts.clone
fu_opts_with_preserve[:preserve] = \
if opts[:preserve] == :try
fsim = File::Stat.instance_methods
(fsim.include?("uid") and fsim.include?("gid") and
fsim.include?("mode") and fsim.include?("atime"))
else
opts[:preserve]
end
changed = []
sources_a = [sources].flatten
sources_a.each do |parent|
Find.find(parent) do |child|
source_fn = File.directory?(child) ? child+"/" : child
target_dir = File.directory?(target)
target_fn = peer_for(source_fn, target)
log.debug(PNOTE+"comparing %s => %s" % [source_fn, target_fn])
source_st = File.stat(source_fn)
is_copy = false
begin
begin
target_st = File.stat(target_fn)
unless target_dir
if source_st.file?
for kind in %w(size mtime)
next if kind == "mtime" and ! opts[:preserve]
unless source_st.send(kind) == target_st.send(kind)
log.debug(PNOTE+"%s not same %s" % [target_fn, kind])
raise EOFError.new
end
end
unless FileUtils.identical?(source_fn, target_fn)
log.debug(PNOTE+"%s not identical" % target_fn)
raise EOFError.new
end
end
if opts[:preserve]
unless source_st.mode == target_st.mode
changed << child
log.debug(PNOTE+"%s not same mode" % target_fn)
chmod(source_st.mode, target_fn, fu_opts)
end
unless source_st.uid == target_st.uid and source_st.gid == target_st.gid
changed << child
log.debug(PNOTE+"%s not same uid/gid" % target_fn)
chown(source_st.uid, source_st.gid, target_fn, fu_opts)
end
end
end
rescue EOFError
changed << child
is_copy = true
end
rescue Errno::ENOENT
changed << child
log.debug(PNOTE+"%s not present" % target_fn)
is_copy = true
end
if is_copy
log.info(PEXEC+"cp%s %s %s" % [opts[:recursive] ? ' -r' : '', source_fn, target_fn])
FileUtils.cp_r(source_fn, target_fn, fu_opts_with_preserve)
end
end
end
result = \
if changed.empty?
false
else
if sources_a.size == 1
changed.first
else
changed.uniq
end
end
return result
end