summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--lib/fileutils.rb16
-rw-r--r--test/fileutils/test_fileutils.rb16
3 files changed, 38 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index d186ad2d68..a633137377 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Sat Feb 2 12:36:54 2013 Yusuke Endoh <mame@tsg.ne.jp>
+
+ * lib/fileutils.rb (copy_entry, wrap_traverse): preserve attributes of
+ directories on FileUtils.cp_r. The fix was proposed by Jan
+ Wedekind. [Bug #7246]
+
+ * test/fileutils/test_fileutils.rb: add a test for above.
+
Sat Feb 2 12:30:00 2013 Zachary Scott <zachary@zacharyscott.net>
* lib/uri/ftp.rb (URI::FTP.new2): nodoc method from r39013 [Bug #7301]
diff --git a/lib/fileutils.rb b/lib/fileutils.rb
index 57ab0cf77a..7bc852ea91 100644
--- a/lib/fileutils.rb
+++ b/lib/fileutils.rb
@@ -526,12 +526,14 @@ public
# If +remove_destination+ is true, this method removes each destination file before copy.
#
def copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
- Entry_.new(src, nil, dereference_root).traverse do |ent|
+ Entry_.new(src, nil, dereference_root).wrap_traverse(proc do |ent|
destent = Entry_.new(dest, ent.rel, false)
File.unlink destent.path if remove_destination && File.file?(destent.path)
ent.copy destent.path
+ end, proc do |ent|
+ destent = Entry_.new(dest, ent.rel, false)
ent.copy_metadata destent.path if preserve
- end
+ end)
end
define_command(:copy_entry)
@@ -1540,6 +1542,16 @@ private
yield self
end
+ def wrap_traverse(pre, post)
+ pre.call self
+ if directory?
+ entries.each do |ent|
+ ent.wrap_traverse pre, post
+ end
+ end
+ post.call self
+ end
+
private
$fileutils_rb_have_lchmod = nil
diff --git a/test/fileutils/test_fileutils.rb b/test/fileutils/test_fileutils.rb
index c1104f31ca..54742d1d18 100644
--- a/test/fileutils/test_fileutils.rb
+++ b/test/fileutils/test_fileutils.rb
@@ -239,6 +239,22 @@ class TestFileUtils
bug4507)
end
+ def test_cp_preserve_permissions_dir
+ bug7246 = '[ruby-core:48603]'
+ mkdir 'tmp/cptmp'
+ mkdir 'tmp/cptmp/d1'
+ chmod 0745, 'tmp/cptmp/d1'
+ mkdir 'tmp/cptmp/d2'
+ chmod 0700, 'tmp/cptmp/d2'
+ cp_r 'tmp/cptmp', 'tmp/cptmp2', :preserve => true
+ assert_equal(File.stat('tmp/cptmp/d1').mode,
+ File.stat('tmp/cptmp2/d1').mode,
+ bug7246)
+ assert_equal(File.stat('tmp/cptmp/d2').mode,
+ File.stat('tmp/cptmp2/d2').mode,
+ bug7246)
+ end
+
def test_cp_symlink
touch 'tmp/cptmp'
# src==dest (2) symlink and its target