Add FileUtils#cp_lr
* lib/fileutils.rb: Add FileUtils#cp_lr. This method creates hard links of each file from directory to another directory recursively. This patch is based on Thomas Sawyers and Zachary Scott. [Feature #4189] [ruby-core:33820] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62739 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
dd3851d278
commit
d583ee266b
6
NEWS
6
NEWS
@ -102,6 +102,12 @@ with all sufficient information, see the ChangeLog file or Redmine
|
||||
|
||||
* erb command's -S option is deprecated, which will be removed in the next version.
|
||||
|
||||
* FileUtils
|
||||
|
||||
* New method:
|
||||
|
||||
* FileUtils#cp_lr [Feature #4189]
|
||||
|
||||
* Matrix
|
||||
|
||||
* New method:
|
||||
|
@ -295,6 +295,39 @@ module FileUtils
|
||||
alias link ln
|
||||
module_function :link
|
||||
|
||||
#
|
||||
# :call-seq:
|
||||
# FileUtils.cp_lr(src, dest, noop: nil, verbose: nil, dereference_root: true, remove_destination: false)
|
||||
#
|
||||
# Hard link +src+ to +dest+. If +src+ is a directory, this method links
|
||||
# all its contents recursively. If +dest+ is a directory, links
|
||||
# +src+ to +dest/src+.
|
||||
#
|
||||
# +src+ can be a list of files.
|
||||
#
|
||||
# # Installing ruby library "mylib" under the site_ruby
|
||||
# FileUtils.rm_r site_ruby + '/mylib', :force => true
|
||||
# FileUtils.cp_lr 'lib/', site_ruby + '/mylib'
|
||||
#
|
||||
# # Examples of copying several files to target directory.
|
||||
# FileUtils.cp_lr %w(mail.rb field.rb debug/), site_ruby + '/tmail'
|
||||
# FileUtils.cp_lr Dir.glob('*.rb'), '/home/aamine/lib/ruby', :noop => true, :verbose => true
|
||||
#
|
||||
# # If you want to copy all contents of a directory instead of the
|
||||
# # directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
|
||||
# # use following code.
|
||||
# FileUtils.cp_lr 'src/.', 'dest' # cp_r('src', 'dest') makes src/dest, but this doesn't.
|
||||
#
|
||||
def cp_lr(src, dest, noop: nil, verbose: nil,
|
||||
dereference_root: true, remove_destination: false)
|
||||
fu_output_message "cp -lr#{remove_destination ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if verbose
|
||||
return if noop
|
||||
fu_each_src_dest(src, dest) do |s, d|
|
||||
link_entry s, d, dereference_root, remove_destination
|
||||
end
|
||||
end
|
||||
module_function :cp_lr
|
||||
|
||||
#
|
||||
# :call-seq:
|
||||
# FileUtils.ln_s(target, link, force: nil, noop: nil, verbose: nil)
|
||||
@ -341,6 +374,26 @@ module FileUtils
|
||||
end
|
||||
module_function :ln_sf
|
||||
|
||||
#
|
||||
# Hard links a file system entry +src+ to +dest+.
|
||||
# If +src+ is a directory, this method links its contents recursively.
|
||||
#
|
||||
# Both of +src+ and +dest+ must be a path name.
|
||||
# +src+ must exist, +dest+ must not exist.
|
||||
#
|
||||
# If +dereference_root+ is true, this method dereference tree root.
|
||||
#
|
||||
# If +remove_destination+ is true, this method removes each destination file before copy.
|
||||
#
|
||||
def link_entry(src, dest, dereference_root = false, remove_destination = false)
|
||||
Entry_.new(src, nil, dereference_root).traverse do |ent|
|
||||
destent = Entry_.new(dest, ent.rel, false)
|
||||
File.unlink destent.path if remove_destination && File.file?(destent.path)
|
||||
ent.link destent.path
|
||||
end
|
||||
end
|
||||
module_function :link_entry
|
||||
|
||||
#
|
||||
# Copies a file content +src+ to +dest+. If +dest+ is a directory,
|
||||
# copies +src+ to +dest/src+.
|
||||
@ -1252,6 +1305,22 @@ module FileUtils
|
||||
end
|
||||
end
|
||||
|
||||
def link(dest)
|
||||
case
|
||||
when directory?
|
||||
if !File.exist?(dest) and descendant_directory?(dest, path)
|
||||
raise ArgumentError, "cannot link directory %s to itself %s" % [path, dest]
|
||||
end
|
||||
begin
|
||||
Dir.mkdir dest
|
||||
rescue
|
||||
raise unless File.directory?(dest)
|
||||
end
|
||||
else
|
||||
File.link path(), dest
|
||||
end
|
||||
end
|
||||
|
||||
def copy(dest)
|
||||
lstat
|
||||
case
|
||||
|
@ -449,6 +449,45 @@ class TestFileUtils < Test::Unit::TestCase
|
||||
cp_r 'tmp/src', 'tmp/dest/', remove_destination: true
|
||||
end if have_symlink?
|
||||
|
||||
def test_cp_lr
|
||||
check_singleton :cp_lr
|
||||
|
||||
cp_lr 'data', 'tmp'
|
||||
TARGETS.each do |fname|
|
||||
assert_same_file fname, "tmp/#{fname}"
|
||||
end
|
||||
|
||||
# a/* -> b/*
|
||||
mkdir 'tmp/cpr_src'
|
||||
mkdir 'tmp/cpr_dest'
|
||||
File.open('tmp/cpr_src/a', 'w') {|f| f.puts 'a' }
|
||||
File.open('tmp/cpr_src/b', 'w') {|f| f.puts 'b' }
|
||||
File.open('tmp/cpr_src/c', 'w') {|f| f.puts 'c' }
|
||||
mkdir 'tmp/cpr_src/d'
|
||||
cp_lr 'tmp/cpr_src/.', 'tmp/cpr_dest'
|
||||
assert_same_file 'tmp/cpr_src/a', 'tmp/cpr_dest/a'
|
||||
assert_same_file 'tmp/cpr_src/b', 'tmp/cpr_dest/b'
|
||||
assert_same_file 'tmp/cpr_src/c', 'tmp/cpr_dest/c'
|
||||
assert_directory 'tmp/cpr_dest/d'
|
||||
my_rm_rf 'tmp/cpr_src'
|
||||
my_rm_rf 'tmp/cpr_dest'
|
||||
|
||||
bug3588 = '[ruby-core:31360]'
|
||||
mkdir 'tmp2'
|
||||
assert_nothing_raised(ArgumentError, bug3588) do
|
||||
cp_lr 'tmp', 'tmp2'
|
||||
end
|
||||
assert_directory 'tmp2/tmp'
|
||||
assert_raise(ArgumentError, bug3588) do
|
||||
cp_lr 'tmp2', 'tmp2/new_tmp2'
|
||||
end
|
||||
|
||||
bug12892 = '[ruby-core:77885] [Bug #12892]'
|
||||
assert_raise(Errno::ENOENT, bug12892) do
|
||||
cp_lr 'non/existent', 'tmp'
|
||||
end
|
||||
end if have_hardlink?
|
||||
|
||||
def test_mv
|
||||
check_singleton :mv
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user