Bug #7246

FileUtils.cp_r does not preserve attributes of directories

Added by Jan Wedekind over 1 year ago. Updated about 1 year ago.

[ruby-core:48603]
Status:Closed
Priority:Normal
Assignee:Yusuke Endoh
Category:lib
Target version:2.0.0
ruby -v:ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin11.3.0] Backport:

Description

(({FileUtils.cp_r})) does not preserve the file attributes of directories because the attributes are set before copying to the directory.
The following monkey patch fixes this behaviour. However the monkey patch relies on the contents of the source directory not changing during the copy operation.

(({require 'fileutils'

def copyentry(src, dest, preserve = false, dereferenceroot = false, removedestination = false)
Entry
.new(src, nil, dereferenceroot).traverse do |ent|
destent = Entry
.new(dest, ent.rel, false)
File.unlink destent.path if removedestination && File.file?(destent.path)
ent.copy destent.path
end
Entry
.new(src, nil, dereferenceroot).postordertraverse do |ent|
destent = Entry.new(dest, ent.rel, false)
ent.copy
metadata destent.path if preserve
end
end
modulefunction :copyentry

end}))

Associated revisions

Revision 39015
Added by Yusuke Endoh about 1 year ago

  • lib/fileutils.rb (copyentry, wraptraverse): 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.

History

#1 Updated by Jan Wedekind over 1 year ago

The following code might be a proper bugfix.

(({require 'fileutils'

module FileUtils

class Entry_

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

end

def copyentry(src, dest, preserve = false, dereferenceroot = false, removedestination = false)
Entry
.new(src, nil, dereferenceroot).wraptraverse(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
modulefunction :copyentry

end}))

#2 Updated by Yusuke Endoh over 1 year ago

  • Status changed from Open to Assigned
  • Assignee set to Yusuke Endoh
  • Target version set to 2.0.0

Thanks, I'll import your fix unless there is objection.

Yusuke Endoh mame@tsg.ne.jp

#3 Updated by Yusuke Endoh about 1 year ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r39015.
Jan, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • lib/fileutils.rb (copyentry, wraptraverse): 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.

Also available in: Atom PDF