directory-tree 0.11.0 → 0.12.0
raw patch · 3 files changed
+137/−27 lines, 3 filesdep +processPVP ok
version bump matches the API change (PVP)
Dependencies added: process
API changes (from Hackage documentation)
+ System.Directory.Tree: transformDir :: (DirTree a -> DirTree a) -> DirTree a -> DirTree a
Files
- System/Directory/Tree.hs +15/−18
- Test.hs +107/−0
- directory-tree.cabal +15/−9
System/Directory/Tree.hs view
@@ -69,6 +69,8 @@ , sortDir , sortDirShape , filterDir+ -- *** Low-level+ , transformDir -- ** Navigation , dropTo -- ** Operators@@ -248,9 +250,7 @@ -- | same as readDirectory but allows us to, for example, use -- ByteString.readFile to return a tree of ByteStrings. readDirectoryWith :: (FilePath -> IO a) -> FilePath -> IO (AnchoredDirTree a)-readDirectoryWith f p = do (b:/t) <- buildWith' buildAtOnce' f p- let t' = removeNonexistent t- return ( b:/t') +readDirectoryWith f p = buildWith' buildAtOnce' f p -- | A "lazy" version of `readDirectoryWith` that does IO operations as needed@@ -258,9 +258,7 @@ -- /NOTE:/ This function uses unsafePerformIO under the hood. I believe our use -- here is safe, but this function is experimental in this release: readDirectoryWithL :: (FilePath -> IO a) -> FilePath -> IO (AnchoredDirTree a)-readDirectoryWithL f p = do (b:/t) <- buildWith' buildLazilyUnsafe' f p- let t' = removeNonexistent t- return ( b:/t') +readDirectoryWithL f p = buildWith' buildLazilyUnsafe' f p -- | write a DirTree of strings to disk. Clobbers files of the same name. @@ -284,7 +282,6 @@ do let bas = b'</>n createDirectoryIfMissing True bas Dir n <$> mapM (write' bas) cs- -- INTERESTING: have to rebuild Failed constr. to get to typecheck: write' _ (Failed n e) = return $ Failed n e @@ -391,7 +388,7 @@ -- | maps a function to convert Failed DirTrees to Files or Dirs failedMap :: (FileName -> IOException -> DirTree a) -> DirTree a -> DirTree a-failedMap f = transform unFail+failedMap f = transformDir unFail where unFail (Failed n e) = f n e unFail c = c @@ -410,7 +407,7 @@ -- HELPER: sortDirBy :: (DirTree a -> DirTree a -> Ordering) -> DirTree a -> DirTree a-sortDirBy cf = transform sortD+sortDirBy cf = transformDir sortD where sortD (Dir n cs) = Dir n (sortBy cf cs) sortD c = c @@ -477,7 +474,7 @@ -- its children, of course) when the predicate returns False. The topmost -- constructor will always be preserved: filterDir :: (DirTree a -> Bool) -> DirTree a -> DirTree a-filterDir p = transform filterD+filterDir p = transformDir filterD where filterD (Dir n cs) = Dir n $ filter p cs filterD c = c @@ -582,17 +579,17 @@ isOkError = not . isDoesNotExistErrorType . ioeGetErrorType . err ----- THIS COULD BE USEFUL TO EXPORT:---- at Dir constructor, apply transformation function to all of directory's--- contents, then remove the Nothing's and recurse.--- ALWAYS PRESERVES TOPMOST CONSTRUCTOR:-transform :: (DirTree a -> DirTree a) -> DirTree a -> DirTree a-transform f t = case f t of- (Dir n cs) -> Dir n $ map (transform f) cs+-- | At 'Dir' constructor, apply transformation function to all of directory's+-- contents, then remove the Nothing's and recurse. This always preserves the+-- topomst constructor.+transformDir :: (DirTree a -> DirTree a) -> DirTree a -> DirTree a+transformDir f t = case f t of+ (Dir n cs) -> Dir n $ map (transformDir f) cs t' -> t' -- Lenses, generated with TH from "lens" -----------+-- TODO deprecate these? Pain in the ass to generate, and maybe it's intended+-- for users to generate their own lenses. _contents :: Applicative f => ([DirTree a] -> f [DirTree a]) -> DirTree a -> f (DirTree a)
+ Test.hs view
@@ -0,0 +1,107 @@+module Main+ where++-- do a quick test for Darcs:++import System.Directory.Tree+import Control.Applicative+import qualified Data.Foldable as F+import System.Directory+import System.Process+import System.IO.Error(ioeGetErrorType,isPermissionErrorType)+import Control.Monad(void)+++++testDir :: FilePath+testDir = "/tmp/TESTDIR-LKJHBAE"++main :: IO ()+main = do+ putStrLn "-- The following tests will either fail with an error "+ putStrLn "-- message or with an 'undefined' error"+ -- write our testing directory structure to disk. We include Failed + -- constructors which should be discarded:+ _:/written <- writeDirectory testTree+ putStrLn "OK"+++ if (fmap (const ()) (filterDir (not . failed) $dirTree testTree)) == + filterDir (not . failed) written+ then return ()+ else error "writeDirectory returned a tree that didn't match"+ putStrLn "OK"++ -- make file farthest to the right unreadable:+ (Dir _ [_,_,Dir "C" [_,_,File "G" p_unreadable]]) <- sortDir . dirTree <$> build testDir+ setPermissions p_unreadable emptyPermissions{readable = False,+ writable = True,+ executable = True,+ searchable = True}+ putStrLn "OK"+++ -- read with lazy and standard functions, compare for equality. Also test that our crazy+ -- operator works correctly inline with <$>:+ tL <- readDirectoryWithL readFile testDir+ t@(_:/Dir _ [_,_,Dir "C" [unreadable_constr,_,_]]) <- sortDir </$> id <$> readDirectory testDir+ if t == tL then return () else error "lazy read /= standard read"+ putStrLn "OK"+ + -- make sure the unreadable file left the correct error type in a Failed:+ if isPermissionErrorType $ ioeGetErrorType $ err unreadable_constr + then return ()+ else error "wrong error type for Failed file read"+ putStrLn "OK"+ + + -- run lazy fold, concating file contents. compare for equality:+ tL_again <- sortDir </$> readDirectoryWithL readFile testDir+ let tL_concated = F.concat $ dirTree tL_again+ if tL_concated == "abcdef" then return () else error "foldable broke"+ putStrLn "OK"++ -- get a lazy DirTree at root directory with lazy Directory traversal:+ putStrLn "-- If lazy IO is not working, we should be stalled right now "+ putStrLn "-- as we try to read in the whole root directory tree."+ putStrLn "-- Go ahead and press CTRL-C if you've read this far"+ mapM_ putStr =<< (map name . contents . dirTree) <$> readDirectoryWithL readFile "/"+ putStrLn "\nOK"+++ let undefinedOrdFailed = Failed undefined undefined :: DirTree Char+ undefinedOrdDir = Dir undefined undefined :: DirTree Char+ undefinedOrdFile = File undefined undefined :: DirTree Char+ -- simple equality and sorting+ if Dir "d" [File "b" "b",File "a" "a"] == Dir "d" [File "a" "a", File "b" "b"] &&+ -- recursive sort order, enforces non-recursive sorting of Dirs+ Dir "d" [Dir "b" undefined,File "a" "a"] /= Dir "d" [File "a" "a", Dir "c" undefined] &&+ -- check ordering of constructors:+ undefinedOrdFailed < undefinedOrdDir &&+ undefinedOrdDir < undefinedOrdFile &&+ -- check ordering by dir contents list length:+ Dir "d" [File "b" "b",File "a" "a"] > Dir "d" [File "a" "a"] &&+ -- recursive ordering on contents:+ Dir "d" [File "b" "b", Dir "c" [File "a" "b"]] > Dir "d" [File "b" "b", Dir "c" [File "a" "a"]] + then putStrLn "OK"+ else error "Ord/Eq instance is messed up"+ + if Dir "d" [File "b" "b",File "a" "a"] `equalShape` Dir "d" [File "a" undefined, File "b" undefined]+ then putStrLn "OK"+ else error "equalShape or comparinghape functions broken"++ -- clean up by removing the directory:+ void $ system $ "rm -r " ++ testDir+ putStrLn "SUCCESS"+ +++testTree :: AnchoredDirTree String+testTree = "" :/ Dir testDir [dA , dB , dC , Failed "FAAAIIILL" undefined]+ where dA = Dir "A" [dA1 , dA2 , Failed "FAIL" undefined]+ dA1 = Dir "A1" [File "A" "a", File "B" "b"]+ dA2 = Dir "A2" [File "C" "c"]+ dB = Dir "B" [File "D" "d"]+ dC = Dir "C" [File "E" "e", File "F" "f", File "G" "g"]+
directory-tree.cabal view
@@ -1,5 +1,5 @@ name: directory-tree-version: 0.11.0+version: 0.12.0 homepage: http://brandon.si/code/directory-tree-module-released/ synopsis: A simple directory-like tree datatype, with useful IO functions description: A simple directory-like tree datatype, with useful IO functions and Foldable and Traversable instance @@ -51,15 +51,13 @@ . Any ideas or suggestions for improvements are most welcome :-) .- /CHANGES/: from 0.10.1- .- - added records for AnchoredDirTree: 'anchor', 'dirTree'+ /CHANGES/: from 0.11 .- - 'free' deprecated in favor of 'dirTree' + - export 'System.Directory.Tree.transformDir' as requested .- - added a new function 'dropTo'+ - add test suite to cabal file .- - implemented lenses compatible with "lens" package+ - remove redundant @removeNonexistent@ (thanks to dmwit for patch) . category: Data, System@@ -68,9 +66,9 @@ copyright: (c) 2011, Brandon Simmons <brandon.m.simmons@gmail.com> author: Brandon Simmons maintainer: Brandon Simmons <brandon.m.simmons@gmail.com>-cabal-version: >= 1.6+cabal-version: >= 1.8 build-type: Simple-tested-with: GHC <=7.4.1+tested-with: GHC <=7.8.2 extra-source-files: EXAMPLES/Examples.hs, EXAMPLES/LazyExamples.hs source-repository head @@ -81,3 +79,11 @@ exposed-modules: System.Directory.Tree build-depends: base <5, filepath <2, directory <2 ghc-options: -Wall++test-suite test+ main-is: Test.hs+ type: exitcode-stdio-1.0+ build-depends: base <5, filepath <2, directory <2+ , process+ ghc-options: -Wall+