Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FileUtis.cp_r cannot overwrite a symlink of directory #9

Merged
merged 1 commit into from
Oct 17, 2017

Conversation

mzp
Copy link
Contributor

@mzp mzp commented Oct 12, 2017

FileUtis.cp_r with remove_destination cannot overwrite a symlink. Though comment of cp_r doesn't provide a detail of this flag, it is good to remove destination symlink file to follow its name.

This problem is same as Bug #13914.

Reproduce code

require 'fileutils'
# setup directory like following:
#
#   tmp
#   ├── dest
#   └── src
#       ├── a -> dir
#           └── dir
#
FileUtils.rm_rf 'tmp'
%w(tmp/src tmp/dest tmp/src/dir).each do|path|
  FileUtils.mkdir_p path
end
File.symlink 'dir', 'tmp/src/a'

# copy dual
FileUtils.cp_r 'tmp/src', 'tmp/dest/', remove_destination: true
FileUtils.cp_r 'tmp/src', 'tmp/dest/', remove_destination: true # <- Errno::EEXIST exception is raised

Actual behavior

$ ruby bug.rb
Traceback (most recent call last):
        13: from bug.rb:18:in `<main>'
        12: from /usr/local/lib/ruby/2.5.0/fileutils.rb:390:in `cp_r'
        11: from /usr/local/lib/ruby/2.5.0/fileutils.rb:1459:in `fu_each_src_dest'
        10: from /usr/local/lib/ruby/2.5.0/fileutils.rb:1475:in `fu_each_src_dest0'
         9: from /usr/local/lib/ruby/2.5.0/fileutils.rb:1461:in `block in fu_each_src_dest'
         8: from /usr/local/lib/ruby/2.5.0/fileutils.rb:391:in `block in cp_r'
         7: from /usr/local/lib/ruby/2.5.0/fileutils.rb:413:in `copy_entry'
         6: from /usr/local/lib/ruby/2.5.0/fileutils.rb:1390:in `wrap_traverse'
         5: from /usr/local/lib/ruby/2.5.0/fileutils.rb:1390:in `each'
         4: from /usr/local/lib/ruby/2.5.0/fileutils.rb:1391:in `block in wrap_traverse'
         3: from /usr/local/lib/ruby/2.5.0/fileutils.rb:1388:in `wrap_traverse'
         2: from /usr/local/lib/ruby/2.5.0/fileutils.rb:416:in `block in copy_entry'
         1: from /usr/local/lib/ruby/2.5.0/fileutils.rb:1268:in `copy'
/usr/local/lib/ruby/2.5.0/fileutils.rb:1268:in `symlink': File exists @ syserr_fail2_in - tmp/dest/src/a (Errno::EEXIST)

Except behavior

This exception should not happen, and tmp/src is copied in a tmp/dest.

Environment

I met this problem at Ruby 2.4.2 on macOS HighSierra and 2.5.0-preview1 on alpine linux.

I use this Dockerfile to test this PR.

Affect of this

Fastlane, major macOS/iOS/Android build tool, is affected by this problem. (fastlane/fastlane#9537)

@hsbt
Copy link
Member

hsbt commented Oct 17, 2017

It's reasonable. Thanks.

@hsbt hsbt merged commit 145e88f into ruby:master Oct 17, 2017
@mzp mzp deleted the remove_destination branch October 18, 2017 14:50
matzbot pushed a commit to ruby/ruby that referenced this pull request Oct 20, 2017
  [Bug #13914][ruby-core:82846] Patch by @mzp
  ruby/fileutils#9

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60218 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
@nobu
Copy link
Member

nobu commented Oct 20, 2017

Not only symlinks, should all other than directory, e.g., device, socket, be removed too?

mrkn pushed a commit to mrkn/ruby that referenced this pull request Dec 1, 2017
  [Bug #13914][ruby-core:82846] Patch by @mzp
  ruby/fileutils#9

git-svn-id: svn+ssh://svn.ruby-lang.org/ruby/trunk@60218 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants