Project

General

Profile

Feature #4189 ยป fileutils_cp_lr.patch

mame (Yusuke Endoh), 03/08/2018 08:29 AM

View differences:

lib/fileutils.rb
295 295
  alias link ln
296 296
  module_function :link
297 297

  
298
  #
299
  # :call-seq:
300
  #   FileUtils.cp_lr(src, dest, noop: nil, verbose: nil, dereference_root: true, remove_destination: false)
301
  #
302
  # Hard link +src+ to +dest+. If +src+ is a directory, this method links
303
  # all its contents recursively. If +dest+ is a directory, links
304
  # +src+ to +dest/src+.
305
  #
306
  # +src+ can be a list of files.
307
  #
308
  #   # Installing ruby library "mylib" under the site_ruby
309
  #   FileUtils.rm_r site_ruby + '/mylib', :force => true
310
  #   FileUtils.cp_lr 'lib/', site_ruby + '/mylib'
311
  #
312
  #   # Examples of copying several files to target directory.
313
  #   FileUtils.cp_lr %w(mail.rb field.rb debug/), site_ruby + '/tmail'
314
  #   FileUtils.cp_lr Dir.glob('*.rb'), '/home/aamine/lib/ruby', :noop => true, :verbose => true
315
  #
316
  #   # If you want to copy all contents of a directory instead of the
317
  #   # directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
318
  #   # use following code.
319
  #   FileUtils.cp_lr 'src/.', 'dest'  # cp_r('src', 'dest') makes src/dest, but this doesn't.
320
  #
321
  def cp_lr(src, dest, noop: nil, verbose: nil,
322
            dereference_root: true, remove_destination: false)
323
    fu_output_message "cp -lr#{remove_destination ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if verbose
324
    return if noop
325
    fu_each_src_dest(src, dest) do |s, d|
326
      link_entry s, d, dereference_root, remove_destination
327
    end
328
  end
329
  module_function :cp_lr
330

  
298 331
  #
299 332
  # :call-seq:
300 333
  #   FileUtils.ln_s(target, link, force: nil, noop: nil, verbose: nil)
......
341 374
  end
342 375
  module_function :ln_sf
343 376

  
377
  #
378
  # Hard links a file system entry +src+ to +dest+.
379
  # If +src+ is a directory, this method links its contents recursively.
380
  #
381
  # Both of +src+ and +dest+ must be a path name.
382
  # +src+ must exist, +dest+ must not exist.
383
  #
384
  # If +dereference_root+ is true, this method dereference tree root.
385
  #
386
  # If +remove_destination+ is true, this method removes each destination file before copy.
387
  #
388
  def link_entry(src, dest, dereference_root = false, remove_destination = false)
389
    Entry_.new(src, nil, dereference_root).traverse do |ent|
390
      destent = Entry_.new(dest, ent.rel, false)
391
      File.unlink destent.path if remove_destination && File.file?(destent.path)
392
      ent.link destent.path
393
    end
394
  end
395
  module_function :link_entry
396

  
344 397
  #
345 398
  # Copies a file content +src+ to +dest+.  If +dest+ is a directory,
346 399
  # copies +src+ to +dest/src+.
......
1252 1305
      end
1253 1306
    end
1254 1307

  
1308
    def link(dest)
1309
      case
1310
      when directory?
1311
        if !File.exist?(dest) and descendant_directory?(dest, path)
1312
          raise ArgumentError, "cannot link directory %s to itself %s" % [path, dest]
1313
        end
1314
        begin
1315
          Dir.mkdir dest
1316
        rescue
1317
          raise unless File.directory?(dest)
1318
        end
1319
      else
1320
        File.link path(), dest
1321
      end
1322
    end
1323

  
1255 1324
    def copy(dest)
1256 1325
      lstat
1257 1326
      case
test/fileutils/test_fileutils.rb
449 449
    cp_r 'tmp/src', 'tmp/dest/', remove_destination: true
450 450
  end if have_symlink?
451 451

  
452
  def test_cp_lr
453
    check_singleton :cp_lr
454

  
455
    cp_lr 'data', 'tmp'
456
    TARGETS.each do |fname|
457
      assert_same_file fname, "tmp/#{fname}"
458
    end
459

  
460
    # a/* -> b/*
461
    mkdir 'tmp/cpr_src'
462
    mkdir 'tmp/cpr_dest'
463
    File.open('tmp/cpr_src/a', 'w') {|f| f.puts 'a' }
464
    File.open('tmp/cpr_src/b', 'w') {|f| f.puts 'b' }
465
    File.open('tmp/cpr_src/c', 'w') {|f| f.puts 'c' }
466
    mkdir 'tmp/cpr_src/d'
467
    cp_lr 'tmp/cpr_src/.', 'tmp/cpr_dest'
468
    assert_same_file 'tmp/cpr_src/a', 'tmp/cpr_dest/a'
469
    assert_same_file 'tmp/cpr_src/b', 'tmp/cpr_dest/b'
470
    assert_same_file 'tmp/cpr_src/c', 'tmp/cpr_dest/c'
471
    assert_directory 'tmp/cpr_dest/d'
472
    my_rm_rf 'tmp/cpr_src'
473
    my_rm_rf 'tmp/cpr_dest'
474

  
475
    bug3588 = '[ruby-core:31360]'
476
    mkdir 'tmp2'
477
    assert_nothing_raised(ArgumentError, bug3588) do
478
      cp_lr 'tmp', 'tmp2'
479
    end
480
    assert_directory 'tmp2/tmp'
481
    assert_raise(ArgumentError, bug3588) do
482
      cp_lr 'tmp2', 'tmp2/new_tmp2'
483
    end
484

  
485
    bug12892 = '[ruby-core:77885] [Bug #12892]'
486
    assert_raise(Errno::ENOENT, bug12892) do
487
      cp_lr 'non/existent', 'tmp'
488
    end
489
  end if have_hardlink?
490

  
452 491
  def test_mv
453 492
    check_singleton :mv
454 493