module Darcs.Util.Tree.Plain
(
readPlainTree
, writePlainTree
) where
import Control.Monad ( forM )
import Data.Maybe( catMaybes )
import qualified Data.ByteString.Lazy as BL
import System.FilePath( (</>) )
import System.Directory ( listDirectory, createDirectoryIfMissing )
import System.Posix.Files
( getSymbolicLinkStatus, isDirectory, isRegularFile, FileStatus )
import Darcs.Prelude
import Darcs.Util.Path
import Darcs.Util.File ( withCurrentDirectory )
import Darcs.Util.ByteString ( readSegment )
import Darcs.Util.Hash( Hash( NoHash) )
import Darcs.Util.Tree( Tree(), TreeItem(..)
, Blob(..), makeTree
, list, readBlob, expand )
readPlainDir :: FilePath -> IO [(FilePath, FileStatus)]
readPlainDir dir =
withCurrentDirectory dir $ do
items <- listDirectory "."
forM items $ \s -> do
st <- getSymbolicLinkStatus s
return (s, st)
readPlainTree :: FilePath -> IO (Tree IO)
readPlainTree dir = do
items <- readPlainDir dir
let subs = catMaybes [
let name = either error id $ makeName name'
in case status of
_ | isDirectory status -> Just (name, Stub (readPlainTree (dir </> name')) NoHash)
_ | isRegularFile status -> Just (name, File $ Blob (readBlob' name') NoHash)
_ -> Nothing
| (name', status) <- items ]
return $ makeTree subs
where readBlob' name = readSegment (dir </> name, Nothing)
writePlainTree :: Tree IO -> FilePath -> IO ()
writePlainTree t dir = do
createDirectoryIfMissing True dir
expand t >>= mapM_ write . list
where write (p, File b) = write' p b
write (p, SubTree _) =
createDirectoryIfMissing True (anchorPath dir p)
write _ = return ()
write' p b = readBlob b >>= BL.writeFile (anchorPath dir p)