mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/fileutils.rb (cp_r): copies symlink to symlink, except cp_r root.
* lib/fileutils.rb: new method FileUtils.copy_entry. * test/fileutils/test_fileutils.rb: more cp_r tests. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6747 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
ab8f2ed967
commit
18c0a86cc6
4 changed files with 265 additions and 81 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
Mon Aug 9 06:33:06 2004 Minero Aoki <aamine@loveruby.net>
|
||||||
|
|
||||||
|
* lib/fileutils.rb (cp_r): copies symlink to symlink, except
|
||||||
|
root entries of cp_r.
|
||||||
|
|
||||||
|
* lib/fileutils.rb: new method FileUtils.copy_entry.
|
||||||
|
|
||||||
|
* test/fileutils/test_fileutils.rb: more cp_r tests.
|
||||||
|
|
||||||
Sun Aug 8 00:43:31 2004 why the lucky stiff <why@ruby-lang.org>
|
Sun Aug 8 00:43:31 2004 why the lucky stiff <why@ruby-lang.org>
|
||||||
|
|
||||||
* lib/implicit.c: added sexagecimal float#base60.
|
* lib/implicit.c: added sexagecimal float#base60.
|
||||||
|
|
249
lib/fileutils.rb
249
lib/fileutils.rb
|
@ -48,7 +48,8 @@
|
||||||
# There are some `low level' methods, which does not accept any option:
|
# There are some `low level' methods, which does not accept any option:
|
||||||
#
|
#
|
||||||
# uptodate?(file, cmp_list)
|
# uptodate?(file, cmp_list)
|
||||||
# copy_file(srcpath, destpath)
|
# copy_entry(src, dest, preserve = false, dereference = false)
|
||||||
|
# copy_file(src, dest, preserve = false, dereference = true)
|
||||||
# copy_stream(srcstream, deststream)
|
# copy_stream(srcstream, deststream)
|
||||||
# compare_file(path_a, path_b)
|
# compare_file(path_a, path_b)
|
||||||
# compare_stream(stream_a, stream_b)
|
# compare_stream(stream_a, stream_b)
|
||||||
|
@ -177,6 +178,14 @@ module FileUtils
|
||||||
|
|
||||||
mode = options[:mode] || (0777 & ~File.umask)
|
mode = options[:mode] || (0777 & ~File.umask)
|
||||||
list.map {|path| path.sub(%r</\z>, '') }.each do |path|
|
list.map {|path| path.sub(%r</\z>, '') }.each do |path|
|
||||||
|
# optimize for the most common case
|
||||||
|
begin
|
||||||
|
Dir.mkdir path
|
||||||
|
next
|
||||||
|
rescue SystemCallError
|
||||||
|
next if File.directory?(path)
|
||||||
|
end
|
||||||
|
|
||||||
stack = []
|
stack = []
|
||||||
until path == stack.last # dirname("/")=="/", dirname("C:/")=="C:/"
|
until path == stack.last # dirname("/")=="/", dirname("C:/")=="C:/"
|
||||||
stack.push path
|
stack.push path
|
||||||
|
@ -322,9 +331,7 @@ module FileUtils
|
||||||
return if options[:noop]
|
return if options[:noop]
|
||||||
|
|
||||||
fu_each_src_dest(src, dest) do |s,d|
|
fu_each_src_dest(src, dest) do |s,d|
|
||||||
fu_preserve_attr(options[:preserve], s, d) {
|
copy_file s, d, options[:preserve]
|
||||||
copy_file s, d
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -346,6 +353,12 @@ module FileUtils
|
||||||
# # Examples of copying several files to target directory.
|
# # Examples of copying several files to target directory.
|
||||||
# FileUtils.cp_r %w(mail.rb field.rb debug/), site_ruby + '/tmail'
|
# FileUtils.cp_r %w(mail.rb field.rb debug/), site_ruby + '/tmail'
|
||||||
# FileUtils.cp_r Dir.glob('*.rb'), '/home/aamine/lib/ruby', :noop, :verbose
|
# FileUtils.cp_r Dir.glob('*.rb'), '/home/aamine/lib/ruby', :noop, :verbose
|
||||||
|
#
|
||||||
|
# # 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_r 'src/.', 'dest' # cp_r('src', 'dest') makes src/dest,
|
||||||
|
# # but this doesn't.
|
||||||
#
|
#
|
||||||
def cp_r(src, dest, options = {})
|
def cp_r(src, dest, options = {})
|
||||||
fu_check_options options, :preserve, :noop, :verbose
|
fu_check_options options, :preserve, :noop, :verbose
|
||||||
|
@ -354,68 +367,53 @@ module FileUtils
|
||||||
|
|
||||||
fu_each_src_dest(src, dest) do |s,d|
|
fu_each_src_dest(src, dest) do |s,d|
|
||||||
if File.directory?(s)
|
if File.directory?(s)
|
||||||
fu_copy_dir s, d, '.', options[:preserve]
|
fu_traverse(s) {|rel, deref, st|
|
||||||
|
ctx = CopyContext_.new(options[:preserve], deref, st)
|
||||||
|
ctx.copy_entry "#{s}/#{rel}", "#{d}/#{rel}"
|
||||||
|
}
|
||||||
else
|
else
|
||||||
fu_p_copy s, d, options[:preserve]
|
copy_file s, d, options[:preserve]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def fu_copy_dir(src, dest, rel, preserve) #:nodoc:
|
def fu_traverse(prefix, dereference_root = true) #:nodoc:
|
||||||
fu_preserve_attr(preserve, "#{src}/#{rel}", "#{dest}/#{rel}") {|s,d|
|
stack = ['.']
|
||||||
begin
|
deref = dereference_root
|
||||||
Dir.mkdir File.expand_path(d)
|
while rel = stack.pop
|
||||||
rescue => err
|
st = File.lstat("#{prefix}/#{rel}")
|
||||||
raise unless File.directory?(d)
|
if st.directory? and (deref or not st.symlink?)
|
||||||
end
|
stack.concat Dir.entries("#{prefix}/#{rel}")\
|
||||||
}
|
.reject {|ent| ent == '.' or ent == '..' }\
|
||||||
Dir.entries("#{src}/#{rel}").each do |fname|
|
.map {|ent| "#{rel}/#{ent}" }.reverse
|
||||||
if File.directory?(File.join(src,rel,fname))
|
|
||||||
next if /\A\.\.?\z/ === fname
|
|
||||||
fu_copy_dir src, dest, "#{rel}/#{fname}", preserve
|
|
||||||
else
|
|
||||||
fu_p_copy File.join(src,rel,fname), File.join(dest,rel,fname), preserve
|
|
||||||
end
|
end
|
||||||
|
yield rel, deref, st
|
||||||
|
deref = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
private :fu_copy_dir
|
private :fu_traverse
|
||||||
|
|
||||||
def fu_p_copy(src, dest, really = true) #:nodoc:
|
|
||||||
fu_preserve_attr(really, src, dest) {
|
|
||||||
copy_file src, dest
|
|
||||||
}
|
|
||||||
end
|
|
||||||
private :fu_p_copy
|
|
||||||
|
|
||||||
def fu_preserve_attr(really, src, dest) #:nodoc:
|
|
||||||
unless really
|
|
||||||
yield src, dest
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
st = File.stat(src)
|
|
||||||
yield src, dest
|
|
||||||
File.utime st.atime, st.mtime, dest
|
|
||||||
begin
|
|
||||||
File.chown st.uid, st.gid, dest
|
|
||||||
rescue Errno::EPERM
|
|
||||||
File.chmod st.mode & 01777, dest # clear setuid/setgid
|
|
||||||
else
|
|
||||||
File.chmod st.mode, dest
|
|
||||||
end
|
|
||||||
end
|
|
||||||
private :fu_preserve_attr
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copies file +src+ to +dest+.
|
# Copies a file system entry +src+ to +dest+.
|
||||||
# Both of +src+ and +dest+ must be a filename.
|
# This method preserves file types, c.f. FIFO, device files, directory....
|
||||||
#
|
#
|
||||||
def copy_file(src, dest)
|
# Both of +src+ and +dest+ must be a path name.
|
||||||
File.open(src, 'rb') {|r|
|
# +src+ must exist, +dest+ must not exist.
|
||||||
File.open(dest, 'wb', r.stat.mode) {|w|
|
#
|
||||||
copy_stream r, w
|
# If +preserve+ is true, this method preserves owner, group and permissions.
|
||||||
}
|
# If +dereference+ is true, this method copies a target of symbolic link
|
||||||
}
|
# instead of a symbolic link itself.
|
||||||
|
#
|
||||||
|
def copy_entry(src, dest, preserve = false, dereference = false)
|
||||||
|
CopyContext_.new(preserve, dereference).copy_entry src, dest
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copies file contents of +src+ to +dest+.
|
||||||
|
# Both of +src+ and +dest+ must be a path name.
|
||||||
|
#
|
||||||
|
def copy_file(src, dest, preserve = false, dereference = true)
|
||||||
|
CopyContext_.new(preserve, dereference).copy_content src, dest
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -423,14 +421,128 @@ module FileUtils
|
||||||
# Both of +src+ and +dest+ must be a IO.
|
# Both of +src+ and +dest+ must be a IO.
|
||||||
#
|
#
|
||||||
def copy_stream(src, dest)
|
def copy_stream(src, dest)
|
||||||
bsize = fu_stream_blksize(src, dest)
|
fu_copy_stream0 src, dest, fu_stream_blksize(src, dest)
|
||||||
|
end
|
||||||
|
|
||||||
|
def fu_copy_stream0(src, dest, blksize) #:nodoc:
|
||||||
begin
|
begin
|
||||||
while true
|
while true
|
||||||
dest.syswrite src.sysread(bsize)
|
dest.syswrite src.sysread(blksize)
|
||||||
end
|
end
|
||||||
rescue EOFError
|
rescue EOFError
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
private :fu_copy_stream0
|
||||||
|
|
||||||
|
class CopyContext_
|
||||||
|
include ::FileUtils
|
||||||
|
|
||||||
|
def initialize(preserve = false, dereference = false, stat = nil)
|
||||||
|
@preserve = preserve
|
||||||
|
@dereference = dereference
|
||||||
|
@stat = stat
|
||||||
|
end
|
||||||
|
|
||||||
|
def copy_entry(src, dest)
|
||||||
|
preserve(src, dest) {
|
||||||
|
_copy_entry src, dest
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def copy_content(src, dest)
|
||||||
|
preserve(src, dest) {
|
||||||
|
_copy_content src, dest
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def _copy_entry(src, dest)
|
||||||
|
st = stat(src)
|
||||||
|
case
|
||||||
|
when st.file?
|
||||||
|
_copy_content src, dest
|
||||||
|
when st.directory?
|
||||||
|
begin
|
||||||
|
Dir.mkdir File.expand_path(dest)
|
||||||
|
rescue => err
|
||||||
|
raise unless File.directory?(dest)
|
||||||
|
end
|
||||||
|
when st.symlink?
|
||||||
|
File.symlink File.readlink(src), dest
|
||||||
|
when st.chardev?
|
||||||
|
raise "cannot handle device file" unless File.respond_to?(:mknod)
|
||||||
|
mknod dest, ?c, 0666, st.rdev
|
||||||
|
when st.blockdev?
|
||||||
|
raise "cannot handle device file" unless File.respond_to?(:mknod)
|
||||||
|
mknod dest, ?b, 0666, st.rdev
|
||||||
|
when st.socket?
|
||||||
|
raise "cannot handle socket" unless File.respond_to?(:mknod)
|
||||||
|
mknod dest, nil, st.mode, 0
|
||||||
|
when st.pipe?
|
||||||
|
raise "cannot handle FIFO" unless File.respond_to?(:mkfifo)
|
||||||
|
mkfifo dest, 0666
|
||||||
|
when (st.mode & 0xF000) == (_S_IF_DOOR = 0xD000) # door
|
||||||
|
raise "cannot handle door: #{src}"
|
||||||
|
else
|
||||||
|
raise "unknown file type: #{src}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def _copy_content(src, dest)
|
||||||
|
st = stat(src)
|
||||||
|
File.open(src, 'rb') {|r|
|
||||||
|
File.open(dest, 'wb', st.mode) {|w|
|
||||||
|
fu_copy_stream0 r, w, (fu_blksize(st) || fu_default_blksize())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def preserve(src, dest)
|
||||||
|
return yield unless @preserve
|
||||||
|
st = stat(src)
|
||||||
|
yield
|
||||||
|
File.utime st.atime, st.mtime, dest
|
||||||
|
begin
|
||||||
|
chown st.uid, st.gid, dest
|
||||||
|
rescue Errno::EPERM
|
||||||
|
# clear setuid/setgid
|
||||||
|
chmod st.mode & 01777, dest
|
||||||
|
else
|
||||||
|
chmod st.mode, dest
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def stat(path)
|
||||||
|
@stat ||= ::File.stat(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def chmod(mode, path)
|
||||||
|
if @dereference
|
||||||
|
::File.chmod mode, path
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
::File.lchmod mode, path
|
||||||
|
rescue NotImplementedError
|
||||||
|
# just ignore this because chmod(symlink) changes attributes of
|
||||||
|
# symlink target, which is not our intent.
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def chown(uid, gid, path)
|
||||||
|
if @dereference
|
||||||
|
::File.chown uid, gid, path
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
::File.lchown uid, gid, path
|
||||||
|
rescue NotImplementedError
|
||||||
|
# just ignore this because chown(symlink) changes attributes of
|
||||||
|
# symlink target, which is not our intent.
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Options: force noop verbose
|
# Options: force noop verbose
|
||||||
|
@ -461,11 +573,7 @@ module FileUtils
|
||||||
File.rename s, d
|
File.rename s, d
|
||||||
rescue SystemCallError
|
rescue SystemCallError
|
||||||
begin
|
begin
|
||||||
if File.symlink?(s)
|
copy_entry s, d, true
|
||||||
File.symlink File.readlink(s), d
|
|
||||||
else
|
|
||||||
fu_p_copy s, d
|
|
||||||
end
|
|
||||||
File.unlink s
|
File.unlink s
|
||||||
rescue SystemCallError
|
rescue SystemCallError
|
||||||
raise unless options[:force]
|
raise unless options[:force]
|
||||||
|
@ -486,7 +594,7 @@ module FileUtils
|
||||||
# Options: force noop verbose
|
# Options: force noop verbose
|
||||||
#
|
#
|
||||||
# Remove file(s) specified in +list+. This method cannot remove directories.
|
# Remove file(s) specified in +list+. This method cannot remove directories.
|
||||||
# All errors are ignored when the :force option is set.
|
# All StandardErrors are ignored when the :force option is set.
|
||||||
#
|
#
|
||||||
# FileUtils.rm %w( junk.txt dust.txt )
|
# FileUtils.rm %w( junk.txt dust.txt )
|
||||||
# FileUtils.rm Dir.glob('*.so')
|
# FileUtils.rm Dir.glob('*.so')
|
||||||
|
@ -767,9 +875,20 @@ module FileUtils
|
||||||
def fu_stream_blksize(*streams)
|
def fu_stream_blksize(*streams)
|
||||||
streams.each do |s|
|
streams.each do |s|
|
||||||
next unless s.respond_to?(:stat)
|
next unless s.respond_to?(:stat)
|
||||||
size = s.stat.blksize
|
size = fu_blksize(s.stat)
|
||||||
return size unless size.nil? or size.zero?
|
return size if size
|
||||||
end
|
end
|
||||||
|
fu_default_blksize()
|
||||||
|
end
|
||||||
|
|
||||||
|
def fu_blksize(st)
|
||||||
|
s = st.blksize
|
||||||
|
return nil unless s
|
||||||
|
return nil if s == 0
|
||||||
|
s
|
||||||
|
end
|
||||||
|
|
||||||
|
def fu_default_blksize
|
||||||
1024
|
1024
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
#
|
# $Id$
|
||||||
# test/fileutils/fileasserts.rb
|
|
||||||
#
|
|
||||||
|
|
||||||
module Test
|
module Test
|
||||||
module Unit
|
module Unit
|
||||||
module Assertions # redefine
|
module Assertions # redefine
|
||||||
|
|
||||||
def assert_same_file( from, to )
|
def assert_same_file(from, to)
|
||||||
_wrap_assertion {
|
_wrap_assertion {
|
||||||
assert_block("file #{from} != #{to}") {
|
assert_block("file #{from} != #{to}") {
|
||||||
File.read(from) == File.read(to)
|
File.read(from) == File.read(to)
|
||||||
|
@ -14,7 +12,22 @@ module Test
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def assert_file_exist( path )
|
def assert_same_entry(from, to)
|
||||||
|
_wrap_assertion {
|
||||||
|
assert_block("entry #{from} != #{to}") {
|
||||||
|
a = File.stat(from)
|
||||||
|
b = File.stat(to)
|
||||||
|
|
||||||
|
a.mode == b.mode and
|
||||||
|
#a.atime == b.atime and
|
||||||
|
a.mtime == b.mtime and
|
||||||
|
a.uid == b.uid and
|
||||||
|
a.gid == b.gid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def assert_file_exist(path)
|
||||||
_wrap_assertion {
|
_wrap_assertion {
|
||||||
assert_block("file not exist: #{path}") {
|
assert_block("file not exist: #{path}") {
|
||||||
File.exist?(path)
|
File.exist?(path)
|
||||||
|
@ -22,7 +35,7 @@ module Test
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def assert_file_not_exist( path )
|
def assert_file_not_exist(path)
|
||||||
_wrap_assertion {
|
_wrap_assertion {
|
||||||
assert_block("file not exist: #{path}") {
|
assert_block("file not exist: #{path}") {
|
||||||
not File.exist?(path)
|
not File.exist?(path)
|
||||||
|
@ -30,7 +43,7 @@ module Test
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def assert_directory( path )
|
def assert_directory(path)
|
||||||
_wrap_assertion {
|
_wrap_assertion {
|
||||||
assert_block("is not directory: #{path}") {
|
assert_block("is not directory: #{path}") {
|
||||||
File.directory?(path)
|
File.directory?(path)
|
||||||
|
@ -38,14 +51,22 @@ module Test
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def assert_symlink( path )
|
def assert_symlink(path)
|
||||||
_wrap_assertion {
|
_wrap_assertion {
|
||||||
assert_block("is no symlink: #{path}") {
|
assert_block("is not a symlink: #{path}") {
|
||||||
File.symlink?(path)
|
File.symlink?(path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def assert_not_symlink(path)
|
||||||
|
_wrap_assertion {
|
||||||
|
assert_block("is a symlink: #{path}") {
|
||||||
|
not File.symlink?(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
#
|
# $Id$
|
||||||
# test/fileutils/test_fileutils.rb
|
|
||||||
#
|
|
||||||
|
|
||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
require 'fileasserts'
|
require 'fileasserts'
|
||||||
|
@ -96,13 +94,12 @@ class TestFileUtils
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
TARGETS = %w( data/same data/all data/random data/zero )
|
TARGETS = %w( data/a data/all data/random data/zero )
|
||||||
|
|
||||||
def prepare_data_file
|
def prepare_data_file
|
||||||
same_chars = 'a' * 50
|
File.open('data/a', 'w') {|f|
|
||||||
File.open('data/same', 'w') {|f|
|
|
||||||
32.times do
|
32.times do
|
||||||
f.puts same_chars
|
f.puts 'a' * 50
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,6 +233,44 @@ end
|
||||||
assert_same_file fname, "tmp/#{fname}"
|
assert_same_file fname, "tmp/#{fname}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
cp_r 'data', 'tmp2', :preserve => true
|
||||||
|
TARGETS.each do |fname|
|
||||||
|
assert_same_entry fname, "tmp/#{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_r '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'
|
||||||
|
rm_rf 'tmp/cpr_src'
|
||||||
|
rm_rf 'tmp/cpr_dest'
|
||||||
|
|
||||||
|
if have_symlink?
|
||||||
|
# symlink in a directory
|
||||||
|
mkdir 'tmp/cpr_src'
|
||||||
|
ln_s 'SLdest', 'tmp/cpr_src/symlink'
|
||||||
|
cp_r 'tmp/cpr_src', 'tmp/cpr_dest'
|
||||||
|
assert_symlink 'tmp/cpr_dest/symlink'
|
||||||
|
assert_equal 'SLdest', File.readlink('tmp/cpr_dest/symlink')
|
||||||
|
|
||||||
|
# root is a symlink
|
||||||
|
ln_s 'cpr_src', 'tmp/cpr_src2'
|
||||||
|
cp_r 'tmp/cpr_src2', 'tmp/cpr_dest2'
|
||||||
|
assert_directory 'tmp/cpr_dest2'
|
||||||
|
assert_not_symlink 'tmp/cpr_dest2'
|
||||||
|
assert_symlink 'tmp/cpr_dest2/symlink'
|
||||||
|
assert_equal 'SLdest', File.readlink('tmp/cpr_dest2/symlink')
|
||||||
|
end
|
||||||
|
|
||||||
# pathname
|
# pathname
|
||||||
touch 'tmp/cprtmp'
|
touch 'tmp/cprtmp'
|
||||||
assert_nothing_raised {
|
assert_nothing_raised {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue