module System.FSNotify.Path
( fp
, findFiles
, findDirs
, canonicalizeDirPath
, canonicalizePath
) where
import Prelude hiding (FilePath)
import Control.Monad
import Filesystem.Path.CurrentOS hiding (concat)
import qualified Filesystem as FS
import qualified Filesystem.Path as FP
class ConvertFilePath a b where
fp :: a -> b
instance ConvertFilePath FilePath String where fp = encodeString
instance ConvertFilePath String FilePath where fp = decodeString
instance ConvertFilePath String String where fp = id
instance ConvertFilePath FilePath FilePath where fp = id
getDirectoryContentsPath :: FilePath -> IO [FilePath]
getDirectoryContentsPath path = fmap (map (path </>)) $ FS.listDirectory path
fileDirContents :: FilePath -> IO ([FilePath],[FilePath])
fileDirContents path = do
contents <- getDirectoryContentsPath path
files <- filterM FS.isFile contents
dirs <- filterM FS.isDirectory contents
return (files, dirs)
findAllFiles :: FilePath -> IO [FilePath]
findAllFiles path = do
(files, dirs) <- fileDirContents path
nestedFiles <- mapM findAllFiles dirs
return (files ++ concat nestedFiles)
findImmediateFiles, findImmediateDirs :: FilePath -> IO [FilePath]
findImmediateFiles = getDirectoryContentsPath >=> filterM FS.isFile >=> canonicalize
where
canonicalize :: [FilePath] -> IO [FilePath]
canonicalize files = mapM FS.canonicalizePath files
findImmediateDirs = getDirectoryContentsPath >=> filterM FS.isDirectory >=> canonicalize
where
canonicalize :: [FilePath] -> IO [FilePath]
canonicalize dirs = mapM canonicalizeDirPath dirs
findAllDirs :: FilePath -> IO [FilePath]
findAllDirs path = do
dirs <- findImmediateDirs path
nestedDirs <- mapM findAllDirs dirs
return (dirs ++ concat nestedDirs)
findFiles :: Bool -> FilePath -> IO [FilePath]
findFiles True path = findAllFiles =<< canonicalizeDirPath path
findFiles False path = findImmediateFiles =<< canonicalizeDirPath path
findDirs :: Bool -> FilePath -> IO [FilePath]
findDirs True path = findAllDirs =<< canonicalizeDirPath path
findDirs False path = findImmediateDirs =<< canonicalizeDirPath path
addTrailingSlash :: FilePath -> FilePath
addTrailingSlash p =
if FP.null (FP.filename p) then p else
p FP.</> FP.empty
canonicalizeDirPath :: FilePath -> IO FilePath
canonicalizeDirPath path = addTrailingSlash `fmap` FS.canonicalizePath path
canonicalizePath :: FilePath -> IO FilePath
canonicalizePath path = let was_dir = FP.null (FP.filename path) in
if not was_dir then FS.canonicalizePath path
else canonicalizeDirPath path