From 270d007e409d972660527ffca96b47f45bb76b20 Mon Sep 17 00:00:00 2001 From: Julian Ospald Date: Fri, 8 May 2020 23:46:39 +0200 Subject: [PATCH] Use streamly-posix for dircontents wrt #34 Also add getDirsFilesStream. --- hpath-directory/CHANGELOG.md | 4 +++ hpath-directory/hpath-directory.cabal | 3 ++- .../src/System/Posix/RawFilePath/Directory.hs | 26 ++++++++++++++----- hpath-io/CHANGELOG.md | 4 +++ hpath-io/hpath-io.cabal | 2 +- hpath-io/src/HPath/IO.hs | 17 ++++++++++-- 6 files changed, 46 insertions(+), 10 deletions(-) diff --git a/hpath-directory/CHANGELOG.md b/hpath-directory/CHANGELOG.md index d5b6f37..566308e 100644 --- a/hpath-directory/CHANGELOG.md +++ b/hpath-directory/CHANGELOG.md @@ -1,5 +1,9 @@ # Revision history for hpath-directory +## 0.13.4 -- 2020-05-08 + +* Add getDirsFilesStream and use streamly-posix for dircontents (#34) + ## 0.13.3 -- 2020-04-14 * Fix tests on mac diff --git a/hpath-directory/hpath-directory.cabal b/hpath-directory/hpath-directory.cabal index 58e27ec..bc3ddc1 100644 --- a/hpath-directory/hpath-directory.cabal +++ b/hpath-directory/hpath-directory.cabal @@ -1,7 +1,7 @@ cabal-version: >=1.10 name: hpath-directory -version: 0.13.3 +version: 0.13.4 synopsis: Alternative to 'directory' package with ByteString based filepaths description: This provides a safer alternative to the 'directory' package. FilePaths are ByteString based, so this @@ -44,6 +44,7 @@ library , safe-exceptions >= 0.1 , streamly >= 0.7 , streamly-bytestring >= 0.1.2 + , streamly-posix >= 0.1.0.0 , time >= 1.8 , unix >= 2.5 , unix-bytestring >= 0.3 diff --git a/hpath-directory/src/System/Posix/RawFilePath/Directory.hs b/hpath-directory/src/System/Posix/RawFilePath/Directory.hs index 6152db3..3da3097 100644 --- a/hpath-directory/src/System/Posix/RawFilePath/Directory.hs +++ b/hpath-directory/src/System/Posix/RawFilePath/Directory.hs @@ -27,7 +27,8 @@ -- Import as: -- > import System.Posix.RawFilePath.Directory -{-# LANGUAGE CPP #-} +{-# LANGUAGE CPP #-} +{-# LANGUAGE FlexibleContexts #-} -- streamly module System.Posix.RawFilePath.Directory ( @@ -82,6 +83,7 @@ module System.Posix.RawFilePath.Directory -- * Directory reading , getDirsFiles , getDirsFiles' + , getDirsFilesStream -- * Filetype operations , getFileType -- * Others @@ -93,8 +95,11 @@ where import Control.Applicative ( (<$>) ) import Control.Exception.Safe ( IOException + , MonadCatch + , MonadMask , bracket , bracketOnError + , onException , throwIO , finally ) @@ -105,6 +110,7 @@ import Control.Monad ( unless import Control.Monad.Catch ( MonadThrow(..) ) import Control.Monad.Fail ( MonadFail ) import Control.Monad.IfElse ( unlessM ) +import Control.Monad.IO.Class ( liftIO ) import qualified Data.ByteString as BS import Data.ByteString ( ByteString ) import Data.Traversable ( for ) @@ -155,6 +161,8 @@ import Streamly import Streamly.External.ByteString import qualified Streamly.External.ByteString.Lazy as SL +import qualified Streamly.External.Posix.DirStream + as SD import qualified Streamly.Data.Fold as FL import Streamly.Memory.Array import qualified Streamly.FileSystem.Handle as FH @@ -1147,11 +1155,17 @@ getDirsFiles p = do -- of prepending the base path. getDirsFiles' :: RawFilePath -- ^ dir to read -> IO [RawFilePath] -getDirsFiles' fp = do - fd <- openFd fp SPI.ReadOnly [SPDF.oNofollow] Nothing - rawContents <- getDirectoryContents' fd - fmap catMaybes $ for rawContents $ \(_, f) -> - if FP.isSpecialDirectoryEntry f then pure Nothing else pure $ Just f +getDirsFiles' fp = getDirsFilesStream fp >>= S.toList + + +-- | Like 'getDirsFiles'', except returning a Stream. +getDirsFilesStream :: (MonadCatch m, MonadAsync m, MonadMask m) + => RawFilePath + -> IO (SerialT m RawFilePath) +getDirsFilesStream fp = do + fd <- openFd fp SPI.ReadOnly [SPDF.oNofollow] Nothing + ds <- SPDT.fdOpendir fd `onException` SPI.closeFd fd + pure $ fmap snd $ SD.dirContentsStream ds diff --git a/hpath-io/CHANGELOG.md b/hpath-io/CHANGELOG.md index baed021..854f452 100644 --- a/hpath-io/CHANGELOG.md +++ b/hpath-io/CHANGELOG.md @@ -1,5 +1,9 @@ # Revision history for hpath-io +## 0.13.2 -- 2020-05-08 + +* Add getDirsFilesStream and use streamly-posix for dircontents (#34) + ## 0.13.0 -- 2020-01-26 * switch to using 'hpath-bytestring' for the implementation (this is now just a wrapper module, mostly) diff --git a/hpath-io/hpath-io.cabal b/hpath-io/hpath-io.cabal index 531df62..9f40dc0 100644 --- a/hpath-io/hpath-io.cabal +++ b/hpath-io/hpath-io.cabal @@ -1,5 +1,5 @@ name: hpath-io -version: 0.13.1 +version: 0.13.2 synopsis: High-level IO operations on files/directories description: High-level IO operations on files/directories, utilizing type-safe Paths -- bug-reports: diff --git a/hpath-io/src/HPath/IO.hs b/hpath-io/src/HPath/IO.hs index f6aec1d..1d4b851 100644 --- a/hpath-io/src/HPath/IO.hs +++ b/hpath-io/src/HPath/IO.hs @@ -27,7 +27,8 @@ -- For other functions (like `copyFile`), the behavior on these file types is -- unreliable/unsafe. Check the documentation of those functions for details. -{-# LANGUAGE PackageImports #-} +{-# LANGUAGE FlexibleContexts #-} -- streamly +{-# LANGUAGE PackageImports #-} module HPath.IO ( @@ -82,6 +83,7 @@ module HPath.IO -- * Directory reading , getDirsFiles , getDirsFiles' + , getDirsFilesStream -- * Filetype operations , getFileType -- * Others @@ -94,7 +96,9 @@ module HPath.IO where -import Control.Exception.Safe ( bracketOnError +import Control.Exception.Safe ( MonadMask + , MonadCatch + , bracketOnError , finally ) import Control.Monad.Catch ( MonadThrow(..) ) @@ -761,6 +765,15 @@ getDirsFiles' (Path fp) = do for rawContents $ \r -> parseRel r +-- | Like 'getDirsFiles'', except returning a Stream. +getDirsFilesStream :: (MonadCatch m, MonadAsync m, MonadMask m) + => Path b + -> IO (SerialT m (Path Rel)) +getDirsFilesStream (Path fp) = do + s <- RD.getDirsFilesStream fp + pure (s >>= parseRel) + + ---------------------------