packages feed

directory-ospath-streaming 0.2.1 → 0.2.2

raw patch · 5 files changed

+61/−6 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ System.Directory.OsPath.Streaming: getDirectoryContentsWithFilterRecursive :: (Basename OsPath -> SymlinkType -> Bool) -> (Basename OsPath -> Bool) -> OsPath -> IO [(OsPath, FileType)]

Files

Changelog.md view
@@ -1,3 +1,7 @@+# 0.2.2++- Add `getDirectoryContentsWithFilterRecursive` for recursively listing directory contents with commonly needed filtering+ # 0.2.1  - Fix `listContentsRecFold` to not mask exceptions unnecessarily which could cause hangups. The `getDirectoryContentsRecursive` gets the fix as well
directory-ospath-streaming.cabal view
@@ -5,7 +5,7 @@ name:   directory-ospath-streaming version:-  0.2.1+  0.2.2 synopsis:   Stream directory entries in constant memory in vanilla IO description:
src/System/Directory/OsPath/Contents.hs view
@@ -11,6 +11,7 @@  module System.Directory.OsPath.Contents   ( getDirectoryContentsRecursive+  , getDirectoryContentsWithFilterRecursive    , listContentsRecFold   ) where@@ -43,6 +44,41 @@     (\_ _ (Relative path) _ ft -> pure (Just (path, ft)))     (Just root) +-- | Recursively list all the files and directories that satisfy given+-- predicate in a directory and all subdirectories. Descending into+-- some subdirectories may be avoided by filtering them out with a+-- visiting predicate.+--+-- Not visited directory entry may still be reported depending on the+-- collection predicate.+--+-- The directory structure is traversed depth-first.+--+-- The result is generated lazily so is not well defined if the source+-- directory structure changes before the list is fully consumed.+--+-- Symlinks within directory structure may cause result to be infinitely long, but+-- they can be filtered out with a suitable directory visiting predicate.+getDirectoryContentsWithFilterRecursive+  :: (Basename OsPath -> SymlinkType -> Bool) -- ^ Whether to visit a directory+  -> (Basename OsPath ->                Bool) -- ^ Whether to collect given directory element, either file or directory.+  -> OsPath+  -> IO [(OsPath, FileType)]+getDirectoryContentsWithFilterRecursive visitPred collectPred root =+  listContentsRecFold'+    Nothing+    (\_ _ (Relative path) basename ft symlink cons prependSubdir rest ->+       (if collectPred basename then cons (path, ft) else id) $+         if visitPred basename symlink+         then prependSubdir rest+         else rest)+    (\_ _ (Relative path) basename ft ->+      pure $+        if collectPred basename+        then Just (path, ft)+        else Nothing)+    (Just root)+ {-# INLINE listContentsRecFold #-} -- | The most general form of gathering directory contents. --@@ -90,7 +126,7 @@  {-# INLINE listContentsRecFold' #-} -- Actual worker with slightly worse type signature that we don’t want to expose to the users.--- But it’s better candidate for implementing getDirectoryContentsRecursive here that+-- But it’s better candidate for implementing getDirectoryContentsRecursive here than -- listContentsRecFold. listContentsRecFold'   :: forall f a b. (Foldable f, Coercible b OsPath)
src/System/Directory/OsPath/Streaming.hs view
@@ -23,6 +23,7 @@    -- * Get directory contents   , getDirectoryContentsRecursive+  , getDirectoryContentsWithFilterRecursive    , listContentsRecFold 
test/TestMain.hs view
@@ -52,17 +52,31 @@           getFileType [osp|test|] >>= (@?= Directory Regular)       ] -  , testCase "getDirectoryContentsRecursive" $ do-    res <- L.sort <$> getDirectoryContentsRecursive [osp|test/filesystem|]-    res @?= [([osp|bar.txt|], File Regular), ([osp|baz.txt|], File Regular), ([osp|bin|], Directory Regular), ([osp|bin|] </> [osp|bin.txt|], File Regular), ([osp|foo.txt|], File Regular)]+  , testGroup "contents"+      [ testCase "getDirectoryContentsRecursive" $ do+          res <- L.sort <$> getDirectoryContentsRecursive [osp|test/filesystem|]+          res @?= [([osp|bar.txt|], File Regular), ([osp|baz.txt|], File Regular), ([osp|bin|], Directory Regular), ([osp|bin|] </> [osp|bin.txt|], File Regular), ([osp|foo.txt|], File Regular)] +      , testCase "getDirectoryContentsWithFilterRecursive 1" $ do+          res <- L.sort <$> getDirectoryContentsWithFilterRecursive (\_ _ -> True) (const True) [osp|test/filesystem|]+          res @?= [([osp|bar.txt|], File Regular), ([osp|baz.txt|], File Regular), ([osp|bin|], Directory Regular), ([osp|bin|] </> [osp|bin.txt|], File Regular), ([osp|foo.txt|], File Regular)]++      , testCase "getDirectoryContentsWithFilterRecursive 2" $ do+          res <- L.sort <$> getDirectoryContentsWithFilterRecursive (\x _ -> x /= Basename [osp|bin|]) (const True) [osp|test/filesystem|]+          res @?= [([osp|bar.txt|], File Regular), ([osp|baz.txt|], File Regular), ([osp|bin|], Directory Regular), ([osp|foo.txt|], File Regular)]++      , testCase "getDirectoryContentsWithFilterRecursive 3" $ do+          res <- L.sort <$> getDirectoryContentsWithFilterRecursive (\_ _ -> True) (`elem` [Basename [osp|foo.txt|], Basename [osp|bin|], Basename [osp|bin.txt|]]) [osp|test/filesystem|]+          res @?= [([osp|bin|], Directory Regular), ([osp|bin|] </> [osp|bin.txt|], File Regular), ([osp|foo.txt|], File Regular)]+      ]+ #ifndef mingw32_HOST_OS   , withResource       (do         tmp <- getTemporaryDirectory >>= canonicalizePath         createFreshTempDir tmp [osp|test|])       removeDirectoryRecursive-      $ \mkTmpDir -> testGroup "getFileType unix"+    $ \mkTmpDir -> testGroup "getFileType unix"         [ testCase "file symlink" $ do             tmp     <- mkTmpDir             currDir <- getCurrentDirectory