The documentation for doesDirectoryExist should read:
The operation 'doesDirectoryExist' returns 'True' if the argument file exists and is either a directory or a symbolic link to a directory, and 'False' otherwise.
Trac metadata
Trac field
Value
Version
7.6.3
Type
Bug
TypeOfFailure
OtherFailure
Priority
normal
Resolution
Unresolved
Component
libraries/directory
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Child items
0
Show closed items
No child items are currently assigned. Use child items to break down this issue into smaller parts.
Linked items
0
Link issues together to show that they're related or that one is blocking others.
Learn more.
#ifdef __GLASGOW_HASKELL__{- |The operation 'doesDirectoryExist' returns 'True' if the argument fileexists and is a directory, and 'False' otherwise.-}doesDirectoryExist :: FilePath -> IO BooldoesDirectoryExist name =#ifdef mingw32_HOST_OS (withFileStatus "doesDirectoryExist" name $ \st -> isDirectory st)#else (do stat <- Posix.getFileStatus name return (Posix.isDirectory stat))#endif `E.catch` ((\ _ -> return False) :: IOException -> IO Bool)
so I just can't see where you are getting this from.
I had a look at what removeDirectoryRecursive is doing and nothing from the source seems to point that it will follow links. It will call ‘unlink’ on the symlink because doesDirectoryExist will return False and therefore will not follow the link. Testing with actual files confirms that calling removeDirectoryRecursive that has the link inside of it in fact does not do anything beyond removing the linked. Directory linked to is intact. Bah, it will never even check if something is the directory unless ‘unlink’ fails somehow at which point we get an exception in Either: ‘Left e’ and only then we check that something is directory. ‘unlink’ will work fine on the symlinks without following them.
If anything, I think that the ‘Be careful’ message should be investigated.
I have satisfied myself that removeDirectoryRecursive will not follow symlinks. Although doesDirectoryExist will return true for a symlink to an existing directory, before that can happen the call to removeFile would remove the symlink. That caution in the documentation can be removed.
I have created testDir: it was one level up. It seems that the formatting swallowed up ‘../’ as is also apparent in your own snippet (so my link was pointing to ‘../testDir’ which existed (I guess ‘/tmp/testDir’ should be used in the future to avoid swallowing up in the WikiFormatting blocks)). Having said that, I did some further investigation and here's what I uncovered:
If the directory linked to exists in the same directory or in any subdirectories, doesDirectoryExists will return True. If the directory linked to exists higher up in the file hierarchy, it will return False. relative/absolute paths seem to not matter.
So a link ‘/tmp/test/linkToSomething’ to ‘/tmp/something’ will return False even if ‘/tmp/something’ is present on the filesystem. A link in ‘/tmp/test/linkToOther’ to ‘/tmp/test/foo/bar/baz/someDir’ will return True given that the someDir exists.
This also means that it might in fact be following symlinks: it just doesn't matter because the only links to return True for directories are in the same/subdirectory that is being removed so they would be gone anyway.
I don't think this strange behaviour is by design and should be fixed, or carefully documented if it is by design.
Apparently I can no longer reproduce this morning and I get True for symlinks. I have no idea how it happened but I must have messed up somewhere when testing. Feel free to ignore my previous posts: I stand corrected. The documentation should be changed to reflect that symbolic links will also return True.