packages feed

pathwalk 0.2.1.0 → 0.3.0.0

raw patch · 5 files changed

+78/−25 lines, 5 filesdep ~base

Dependency ranges changed: base

Files

+ examples/basic/Main.hs view
@@ -0,0 +1,15 @@+module Main (main) where++import Control.Monad (forM_)+import System.Directory.PathWalk (pathWalk)+import System.Environment (getArgs)++main :: IO ()+main = do+  rawArgs <- getArgs+  let args = if rawArgs == [] then ["."] else rawArgs+  forM_ args $ \arg -> do+    pathWalk arg $ \root dirs files -> do+      putStrLn root+      putStrLn $ "  dirs: " ++ show dirs+      putStrLn $ "  files: " ++ show files
− examples/example/Main.hs
@@ -1,15 +0,0 @@-module Main (main) where--import Control.Monad (forM_)-import System.Directory.PathWalk (pathWalk)-import System.Environment (getArgs)--main :: IO ()-main = do-  rawArgs <- getArgs-  let args = if rawArgs == [] then ["."] else rawArgs-  forM_ args $ \arg -> do-    pathWalk arg $ \root dirs files -> do-      putStrLn root-      putStrLn $ "  dirs: " ++ show dirs-      putStrLn $ "  files: " ++ show files
+ examples/lazy/Main.hs view
@@ -0,0 +1,16 @@+module Main (main) where++import Control.Monad (forM_)+import System.Directory.PathWalk (pathWalkLazy)+import System.Environment (getArgs)++main :: IO ()+main = do+  rawArgs <- getArgs+  let args = if rawArgs == [] then ["."] else rawArgs+  forM_ args $ \arg -> do+    results <- pathWalkLazy arg+    forM_ results $ \(root, dirs, files) -> do+      putStrLn root+      putStrLn $ "  dirs: " ++ show dirs+      putStrLn $ "  files: " ++ show files
pathwalk.cabal view
@@ -1,5 +1,5 @@ name:                pathwalk-version:             0.2.1.0+version:             0.3.0.0 synopsis:            Path walking utilities for Haskell programs description:         Simple directory tree walking utilities. license:             MIT@@ -44,16 +44,26 @@   default-language: Haskell2010   ghc-options: -Wall -executable example+test-suite basic+  type: exitcode-stdio-1.0   main-is: Main.hs   build-depends: base, pathwalk-  hs-source-dirs: examples/example+  hs-source-dirs: examples/basic   default-language: Haskell2010   ghc-options: -Wall -executable stoprecursing+test-suite stoprecursing+  type: exitcode-stdio-1.0   main-is: Main.hs   build-depends: base, pathwalk   hs-source-dirs: examples/stoprecursing+  default-language: Haskell2010+  ghc-options: -Wall++test-suite lazy+  type: exitcode-stdio-1.0+  main-is: Main.hs+  build-depends: base, pathwalk+  hs-source-dirs: examples/lazy   default-language: Haskell2010   ghc-options: -Wall
src/System/Directory/PathWalk.hs view
@@ -5,18 +5,21 @@     , pathWalk     , WalkStatus(..)     , pathWalkInterruptible+    , pathWalkLazy     ) where -import Control.Monad (forM_, filterM)+import Control.Monad (forM, forM_, filterM)+import Control.Monad.IO.Class (MonadIO, liftIO) import System.Directory (doesDirectoryExist, doesFileExist, getDirectoryContents) import System.FilePath ((</>)) import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)+import System.IO.Unsafe (unsafeInterleaveIO)  -- | Called with a directory, list of relative subdirectories, and a -- list of file names.  If using 'pathWalk', the callback always -- returns '()'.  If using 'pathWalkInterruptible', it returns whether -- to continue, prevent recursing further, or stop traversal entirely.-type Callback a = FilePath -> [FilePath] -> [FilePath] -> IO a+type Callback m a = FilePath -> [FilePath] -> [FilePath] -> m a  -- | 'pathWalk' recursively enumerates the given root directory, -- calling callback once per directory with the traversed directory@@ -31,7 +34,7 @@ --     when ("Test.hs" \`isSuffixOf\` file) $ do --       registerTestFile $ dir \</\> file -- @-pathWalk :: FilePath -> Callback () -> IO ()+pathWalk :: MonadIO m => FilePath -> Callback m () -> m () pathWalk root callback = do   pathWalkInterruptible root $ \dir dirs files -> do     callback dir dirs files@@ -45,14 +48,20 @@   | Stop -- ^ Stop recursing entirely.   deriving (Show, Eq) -pathWalkInternal :: FilePath -> Callback WalkStatus -> IO (Maybe ())-pathWalkInternal root callback = do+readDirsAndFiles :: FilePath -> IO ([FilePath], [FilePath])+readDirsAndFiles root = do   names <- getDirectoryContents root   let properNames = filter (`notElem` [".", ".."]) names    dirs <- filterM (\n -> doesDirectoryExist $ root </> n) properNames   files <- filterM (\n -> doesFileExist $ root </> n) properNames+  +  return (dirs, files) +pathWalkInternal :: MonadIO m => FilePath -> Callback m WalkStatus -> m (Maybe ())+pathWalkInternal root callback = do+  (dirs, files) <- liftIO $ readDirsAndFiles root+   result <- callback root dirs files   case result of     Continue -> do@@ -67,7 +76,25 @@ -- | Traverses a directory tree, just like 'pathWalk', except that -- the callback can determine whether to continue traversal.  See -- 'WalkStatus'.-pathWalkInterruptible :: FilePath -> Callback WalkStatus -> IO ()+pathWalkInterruptible :: MonadIO m => FilePath -> Callback m WalkStatus -> m () pathWalkInterruptible root callback = do   _ <- pathWalkInternal root callback   return ()++-- | The lazy version of 'pathWalk'.  Instead of running a callback+-- per directory, it returns a lazy list that reads from the+-- filesystem as the list is evaluated.+--+-- 'pathWalkLazy' does not allow selective recursion.  For richer+-- functionality, see the directory-tree package at+-- https://hackage.haskell.org/package/directory-tree+pathWalkLazy :: MonadIO m => FilePath -> m [(FilePath, [FilePath], [FilePath])]+pathWalkLazy root = liftIO $ unsafeInterleaveIO $ do+  (dirs, files) <- readDirsAndFiles root++  next <- unsafeInterleaveIO $ do+    allsubs <- forM dirs $ \dir -> do+      pathWalkLazy $ root </> dir+    return $ concat allsubs+    +  return $ (root, dirs, files) : next