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
(PUP-5018) Cannot unlink dangling Windows symlinks #4147
(PUP-5018) Cannot unlink dangling Windows symlinks #4147
Conversation
@@ -62,7 +62,9 @@ def unlink(*file_names) | |||
stat = Puppet::Util::Windows::File.stat(file_name) rescue nil | |||
|
|||
# sigh, Ruby + Windows :( | |||
if stat && stat.ftype == 'directory' | |||
if !stat |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now I understand what you meant by nil
coming back.
a599f60
to
da86ca3
Compare
Once it's green it's gold. |
Puppet::FileSystem.unlink(symlink) | ||
|
||
expect(Puppet::FileSystem.exist?(dir)).to be_falsey | ||
expect(Puppet::FileSystem.exist?(dir)).to be_falsey |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh shoot.. typo here.
da86ca3
to
ba44550
Compare
::File.delete(file) | ||
Puppet::FileSystem.unlink(symlink) | ||
|
||
expect(Puppet::FileSystem.exist?(file)).to be_falsey |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor nit, for predicate methods you'll get better error messages if you do something like:
expect(Puppet::FileSystem).to_not be_exist(file)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 repushed
- When a symlink is created to point at a directory, then that target directory is removed, Windows was previously generating `Errno::EACCES: Permission denied @ unlink_internal` because the underlying Ruby File.unlink was being called, which fails on Windows. When the target no longer exists, Ruby's File.unlink only works properly on symlinks pointed at files and not symlinks pointed at directories. Given the lstat only specifies 'link' and does not describe the target, there is no way of knowing whether the former target was a file or directory. Thefore, when the target stat does not exist, first attempt to File.unlink, and if that fails call Dir.rmdir. Ruby's Dir.rmdir only works on links that were targeted at directories, and not links that were targeted at files.
ba44550
to
579d5ea
Compare
This looks good to move in. |
…-unlink-fails-on-orphaned-links (PUP-5018) Cannot unlink dangling Windows symlinks
Merged to master at 7a87738 |
When a symlink is created to point at a directory, then that target
directory is removed, Windows was previously generating
Errno::EACCES: Permission denied @ unlink_internal
because theunderlying Ruby File.unlink was being called, which fails on Windows.
When the target no longer exists, Ruby's File.unlink only works
properly on symlinks pointed at files and not symlinks pointed at
directories
Given the lstat only specifies 'link' and does not describe the
target, there is no way of knowing whether the former target was a
file or directory. Thefore, when the target stat does not exist,
first attempt to File.unlink, and if that fails call Dir.rmdir.
Ruby's Dir.rmdir only works on links that were targeted at
directories, and not links that were targeted at files.