filesystem-trees 0.1 → 0.1.0.1
raw patch · 2 files changed
+32/−13 lines, 2 filesdep +deepseqPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
Dependencies added: deepseq
API changes (from Hackage documentation)
+ System.File.Tree: instance NFData FSTree
+ System.File.Tree: levels :: FSTree -> [[FilePath]]
Files
- filesystem-trees.cabal +2/−1
- src/System/File/Tree.hs +30/−12
filesystem-trees.cabal view
@@ -1,5 +1,5 @@ Name: filesystem-trees-Version: 0.1+Version: 0.1.0.1 Synopsis: Recursively manipulate and traverse filesystems as lazy rose trees. Cabal-Version: >= 1.10 License: BSD3@@ -24,4 +24,5 @@ , dlist >= 0.2 && < 1.0 , mtl >= 1.0 && < 3.0 , cond >= 0.3 && < 0.5+ , deepseq >= 1.1 && < 1.5 exposed-modules: System.File.Tree
src/System/File/Tree.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE GeneralizedNewtypeDeriving, DeriveDataTypeable, +{-# LANGUAGE CPP, GeneralizedNewtypeDeriving, DeriveDataTypeable, FlexibleInstances, MultiParamTypeClasses, FunctionalDependencies, TypeSynonymInstances, RankNTypes #-}@@ -22,7 +22,7 @@ , remove, tryRemove, tryRemoveWith -- * Operations on directory trees -- **basic operations- , pop, pop_, flatten, flattenPostOrder+ , pop, pop_, flatten, flattenPostOrder, levels -- ** map over subtrees , map, mapM, mapM_ -- **find subtrees@@ -50,10 +50,11 @@ import System.Posix.Files (getSymbolicLinkStatus, isSymbolicLink) import Data.Tree (Tree(..), Forest)-import qualified Data.Tree as Tree (flatten)+import qualified Data.Tree as Tree (flatten, levels) import Data.DList as DL (DList(..), cons, append, toList, empty, concat, snoc) import Control.Exception (throwIO, catch, IOException)+import System.IO.Error (ioeGetErrorType, doesNotExistErrorType) import Control.Monad (forM, liftM, liftM2, void) import Control.Monad.Identity (runIdentity) import Control.Applicative ((<$>), (<*>), (<*))@@ -63,8 +64,10 @@ import Data.Maybe (mapMaybe, catMaybes) import Data.Function (on) import Data.Lens.Common (Lens, lens, getL, setL, modL)+import Control.DeepSeq (NFData(..), deepseq) import Control.Conditional (ifM, (<&&>), (<||>), notM, condM, otherwiseM) + import Data.Word (Word) import Data.Typeable (Typeable) import Data.Data (Data)@@ -112,6 +115,9 @@ newtype FSTree = FSTree { toTree :: Tree FilePath } deriving (Typeable, Data, Eq, Read, Show) +instance NFData FSTree where+ rnf t = getL label t `deepseq` rnf (getL children t)+ type FSForest = [FSTree] -- |A pseudo-constructor for 'FSTree'.@@ -179,9 +185,19 @@ isDir :: FilePath -> IO Bool isDir = doesDirectoryExist --- |Checks if a path refers to a symbolic link+-- |Checks if a path refers to a symbolic link.+-- NOTE: always returns False on Windows isSymLink :: FilePath -> IO Bool-isSymLink p = isSymbolicLink <$> getSymbolicLinkStatus p+#if CABAL_OS_WINDOWS+isSymLink p = return False+#else+isSymLink p = (isSymbolicLink <$> getSymbolicLinkStatus p)+ `catch` handler+ where handler :: IOError -> IO Bool + handler e+ | ioeGetErrorType e == doesNotExistErrorType = return False+ | otherwise = throwIO e+#endif -- |Checks if a path refers to a symbolically linked directory isSymDir :: FilePath -> IO Bool@@ -222,6 +238,10 @@ flattenPostOrder = toList . flatten' . prependPaths where flatten' (Node p cs) = DL.concat (P.map flatten' cs) `snoc` p +-- |List of file paths at each level of the tree.+levels :: FSTree -> [[FilePath]]+levels = Tree.levels . prependPaths+ -- |Applies a function over the filepaths of a directory tree. -- -- Because we can't guarantee that the internal 'FSTree' representation is preserved @@ -247,11 +267,10 @@ find :: (FilePath -> Bool) -> FSForest -> FSForest find p = snd . extract p --- |A generalization of 'find'. The first element of the result --- represents the forest after removing all subtrees that match the given predicate, --- and the second element is a list of trees that matched. This could be useful if --- you want to handle certain directories specially from others within a --- sub-filesystem.+-- |The first element of the result represents the forest after removing all +-- subtrees that match the given predicate, and the second element is a list of +-- trees that matched. This could be useful if you want to handle certain +-- directories specially from others within a sub-filesystem. extract :: (FilePath -> Bool) -> FSForest -> (FSForest, FSForest) extract p = runIdentity . extractM (return . p) @@ -341,8 +360,7 @@ ] zipWithDestM_ (\s d -> ifM (isRealDir s) - (do tryRemoveDirectory s- createDirectory d)+ (createDirectory d) (renameFile s d) ) dest fs