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

Make behavior of removeDirectoryRecursive more consistent #16

Merged
merged 1 commit into from
Feb 22, 2015

Conversation

Rufflewind
Copy link
Member

Fixes #15.

While the POSIX-like behavior is more elegant to implement, for backward compatibility removeDirectoryRecursive shall retain the Python-like behavior. Another function removePathRecursive was added to implement the POSIX behavior, although it is currently not exported.

The way `removeDirectoryRecursive dir` works right now is totally
inconsistent:

  - If there's a directory-like symbolic link, the function removes it
    without recursing into it, *unless* the symbolic link is not
    removable for some reason (e.g. no permission), in which case it
    recurses into it and wipes out everything inside.

  - If `dir` itself is actually a directory-like symbolic link, it will
    recurse into it but fail to remove `dir` itself.

The causes of these two problems are:

  - Instead of explicitly checking whether path refers to a true
    directory, it assumes any unremovable file that also satisfies
    `directoryExists` must necessarily be a directory.  This is false,
    because `directoryExists` dereferences the symbolic link.

  - `getDirectoryContents` should not be called until `dir` is verified
    to be a true directory.

There are two possible ways to handle the case where `dir` is not a true
directory:

  - One can delete it silently, similar to the behavior of the POSIX
    command `rm -r`.

  - Or one can raise an error, similar to the behavior of the Python
    function `shutil.rmtree`.

The former is more elegant to implement but for backward compatibility
`removeDirectoryRecursive` shall retain the Python-like behavior.
Another function `removePathRecursive` was added to implement the POSIX
behavior, although the decision of to export this function will be left
for the future.

On Windows, there are two kinds of symbolic links:

  - directory symbolic links, and
  - file symbolic links.

Directory symbolic links are treated as directories on Windows, which
means `lstat` considers them directories and `DeleteFile` doesn't work.
To remedy this, `removePathRecursive` was tweaked to handle these
unusual cases and avoid following symbolic links.
@Rufflewind Rufflewind force-pushed the remove-directory-recursive branch from 4a83c8c to ca34a87 Compare February 22, 2015 00:17
Rufflewind added a commit that referenced this pull request Feb 22, 2015
Make behavior of removeDirectoryRecursive more consistent
@Rufflewind Rufflewind merged commit cd7b52e into haskell:master Feb 22, 2015
@Rufflewind Rufflewind deleted the remove-directory-recursive branch March 3, 2015 04:42
@Rufflewind Rufflewind restored the remove-directory-recursive branch March 3, 2015 04:42
@Rufflewind Rufflewind deleted the remove-directory-recursive branch March 3, 2015 04:42
bgamari pushed a commit to bgamari/directory that referenced this pull request Jul 29, 2016
bgamari pushed a commit to bgamari/directory that referenced this pull request Jul 29, 2016
Bug fix: equalFilePath "C:\\" "C:" == False
bgamari pushed a commit to bgamari/directory that referenced this pull request Jul 29, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

inconsistent behavior of removeDirectoryRecursive with symbolic links
1 participant