packages feed

directory 1.2.7.0 → 1.2.7.1

raw patch · 4 files changed

+64/−18 lines, 4 filesdep ~Win32dep ~basedep ~timePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: Win32, base, time

API changes (from Hackage documentation)

Files

System/Directory.hs view
@@ -570,33 +570,68 @@     mapM_ removePathRecursive [path </> x | x <- cont]     removeDirectory path --- | @'removePathForcibly@ removes a file or directory at /path/ together with--- its contents and subdirectories. Symbolic links are removed without--- affecting their the targets. If the path does not exist, nothing happens.+-- | Removes a file or directory at /path/ together with its contents and+-- subdirectories. Symbolic links are removed without affecting their+-- targets. If the path does not exist, nothing happens. -- -- Unlike other removal functions, this function will also attempt to delete -- files marked as read-only or otherwise made unremovable due to permissions. -- As a result, if the removal is incomplete, the permissions or attributes on -- the remaining files may be altered.+--+-- If an entry within the directory vanishes while @removePathForcibly@ is+-- running, it is silently ignored.+--+-- If an exception occurs while removing an entry, @removePathForcibly@ will+-- still try to remove as many entries as it can before failing with an+-- exception.  The first exception that it encountered is re-thrown.+--+-- @since 1.2.7.0 removePathForcibly :: FilePath -> IO () removePathForcibly path =   (`ioeSetLocation` "removePathForcibly") `modifyIOError` do     makeRemovable path `catchIOError` \ _ -> return ()-    dirType <- tryIOErrorType isDoesNotExistError (getDirectoryType path)-    case dirType of-      Left _              -> return ()-      Right NotDirectory  -> removeFile path-      Right DirectoryLink -> removeDirectory path-      Right Directory     -> do-        mapM_ (removePathForcibly . (path </>)) =<< listDirectory path-        removeDirectory path+    ignoreDoesNotExistError $ do+      dirType <- getDirectoryType path+      case dirType of+        NotDirectory  -> removeFile path+        DirectoryLink -> removeDirectory path+        Directory     -> do+          names <- listDirectory path+          sequenceWithIOErrors_ $+            [ removePathForcibly (path </> name) | name <- names ] +++            [ removeDirectory path ]   where++    ignoreDoesNotExistError :: IO () -> IO ()+    ignoreDoesNotExistError action = do+      _ <- tryIOErrorType isDoesNotExistError action+      return ()++    makeRemovable :: FilePath -> IO ()     makeRemovable p = do       perms <- getPermissions p       setPermissions path perms{ readable = True                                , searchable = True                                , writable = True } +sequenceWithIOErrors_ :: [IO ()] -> IO ()+sequenceWithIOErrors_ actions = go (Right ()) actions+  where++    go :: Either IOError () -> [IO ()] -> IO ()+    go (Left e)   []       = ioError e+    go (Right ()) []       = return ()+    go s          (m : ms) = s `seq` do+      r <- tryIOError m+      go (thenEither s r) ms++    -- equivalent to (*>) for Either, defined here to retain compatibility+    -- with base prior to 4.3+    thenEither :: Either b a -> Either b a -> Either b a+    thenEither x@(Left _) _ = x+    thenEither _          y = y+ {- |'removeFile' /file/ removes the directory entry for an existing file /file/, where /file/ is not itself a directory. The implementation may specify additional constraints which must be@@ -633,7 +668,7 @@  removeFile :: FilePath -> IO () removeFile path =-#if mingw32_HOST_OS+#ifdef mingw32_HOST_OS   Win32.deleteFile path #else   Posix.removeLink path@@ -814,6 +849,7 @@ -- parent segments in the destination path is not a directory. -- @[ENOTDIR, EISDIR, EINVAL, EEXIST, ENOTEMPTY]@ --+-- @since 1.2.7.0 renamePath :: FilePath                  -- ^ Old path            -> FilePath                  -- ^ New path            -> IO ()@@ -1395,6 +1431,8 @@     action  -- | Obtain the size of a file in bytes.+--+-- @since 1.2.7.0 getFileSize :: FilePath -> IO Integer getFileSize path =   (`ioeSetLocation` "getFileSize") `modifyIOError` do@@ -1407,6 +1445,8 @@ -- | Test whether the given path points to an existing filesystem object.  If -- the user lacks necessary permissions to search the parent directories, this -- function may return false even if the file does actually exist.+--+-- @since 1.2.7.0 doesPathExist :: FilePath -> IO Bool doesPathExist path = #ifdef mingw32_HOST_OS
changelog.md view
@@ -1,6 +1,12 @@ Changelog for the [`directory`][1] package ========================================== +## 1.2.7.1 (November 2016)++  * Don't abort `removePathForcibly` if files or directories go missing.+    In addition, keep going even if an exception occurs.+    ([#60](https://github.com/haskell/directory/issues/60))+ ## 1.2.7.0 (August 2016)    * Remove deprecated C bits.  This means `HsDirectory.h` and its functions@@ -41,7 +47,7 @@    * Add `findFileWith` -  * Add `copyFileWithAttrs`, which copies additional metadata+  * Add `copyFileWithMetadata`, which copies additional metadata     ([#40](https://github.com/haskell/directory/issues/40))    * Improve error message of `removeDirectoryRecursive` when used on a
directory.cabal view
@@ -1,5 +1,5 @@ name:           directory-version:        1.2.7.0+version:        1.2.7.1 -- NOTE: Don't forget to update ./changelog.md license:        BSD3 license-file:   LICENSE@@ -52,11 +52,11 @@     include-dirs: .      build-depends:-        base     >= 4.5 && < 4.10,-        time     >= 1.4 && < 1.7,+        base     >= 4.5 && < 4.11,+        time     >= 1.4 && < 1.8,         filepath >= 1.3 && < 1.5     if os(windows)-        build-depends: Win32 >= 2.2.2 && < 2.4+        build-depends: Win32 >= 2.2.2 && < 2.5     else         build-depends: unix >= 2.5.1 && < 2.8 
tests/TestUtils.hs view
@@ -52,7 +52,7 @@   permissions <- getPermissions path   setPermissions path (modify permissions) -#if mingw32_HOST_OS+#ifdef mingw32_HOST_OS createSymbolicLink :: String -> String -> IO () createSymbolicLink target link =   (`ioeSetLocation` "createSymbolicLink") `modifyIOError` do