Bug #2731
closedFileUtils.copy prints error message in $DEBUG mode when destination doesn't exist
Description
=begin
Trying to copy a file with Ruby:
$ touch source
$ ls destination
ls: destination: No such file or directory
$ ruby -rfileutils -d -e 'FileUtils.copy "source", "destination"'
Exception `Errno::ENOENT' at /usr/local/lib/ruby/1.9.1/fileutils.rb:1429 - No such file or directory - destination
$ ls destination
destination
While the copy succeeds, it prints this confusing message. I don't expect libraries to issue exceptions when performing standard operations. This affects the FileUtils methods install, mv, cp_r, and cp; but the problem is in Entry_#fu_same? (around lib/fileutils.rb:1426):
def fu_same?(a, b) #:nodoc:
if fu_have_st_ino?
st1 = File.stat(a)
st2 = File.stat(b)
st1.dev == st2.dev and st1.ino == st2.ino
else
File.expand_path(a) == File.expand_path(b)
end
rescue Errno::ENOENT
return false
end
So, File.stat(b) is checked even if b doesn't exist. The resulting error message is even explicitely captured and hidden by the rescue. For the methods in question, it is a common case that the destination file doesn't exist.
Here's a version that doesn't rely on exceptions:
def fu_same?(a, b) #:nodoc:
return false if !File.exist?(a) || !File.exist?(b)
if fu_have_st_ino?
st1 = File.stat(a)
st2 = File.stat(b)
st1.dev == st2.dev and st1.ino == st2.ino
else
File.expand_path(a) == File.expand_path(b)
end
end
The problem exists across Ruby versions from 1.8.6 to 1.9.2dev.
=end