-- | Directory utils that don't need to be in the Build monad. module BuildBox.IO.Directory ( lsFilesIn , lsDirsIn , traceFilesFrom) where import System.Directory import Control.Monad import Control.Monad.Trans import Data.List import Data.Sequence (Seq) import qualified Data.Sequence as Seq -- | Get the names of all files in a directory. -- This filters out the fake files like '.' and '..' lsFilesIn :: MonadIO m => String -> m [String] lsFilesIn path = do contents <- liftIO $ getDirectoryContents path -- filter out directories files <- filterM (\p -> liftM not $ liftIO $ doesDirectoryExist p) $ map (\f -> path ++ "/" ++ f) $ dropDotPaths contents return $ sort files -- | Get the names of all the dirs in this one. -- This filters out the fake files like '.' and '..' lsDirsIn :: MonadIO m => String -> m [String] lsDirsIn path = do contents <- liftIO $ getDirectoryContents path -- only keep directories dirs <- filterM (liftIO . doesDirectoryExist) $ map (\f -> path ++ "/" ++ f) $ dropDotPaths contents return $ sort dirs -- | Get all the files reachable from this directory traceFilesFrom :: FilePath -> IO (Seq FilePath) traceFilesFrom path = do isDir <- doesDirectoryExist path isFile <- doesFileExist path let result | isDir = do contents <- liftM dropDotPaths $ getDirectoryContents path liftM (join . Seq.fromList) $ mapM traceFilesFrom $ map (\f -> path ++ "/" ++ f) $ contents | isFile = return $ Seq.singleton path | otherwise = return $ Seq.empty result -- | Drop out the fake '.' and '..' dirst from a list of paths. dropDotPaths :: [FilePath] -> [FilePath] dropDotPaths xx = filter (\f -> f /= "." && f /= "..") xx