module System.FilePath.Finder ( findFiles ) where import Control.Monad (filterM) import System.Directory (doesDirectoryExist, doesFileExist, listDirectory) import System.FilePath.Posix (takeExtension, takeFileName, ()) findFiles :: [String] -> [String] -> FilePath -> IO [FilePath] findFiles extensions excludedDirs dir = do exist <- doesDirectoryExist dir let excluded = (takeFileName dir) `elem` excludedDirs if not exist || excluded then return [] else do entries <- listDirectory dir let paths = map (dir ) entries files <- filterM doesFileExist paths let foundFiles = filter (hasExtension extensions) files dirs <- filterM doesDirectoryExist paths foundFilesInDirs <- mapM (findFiles extensions excludedDirs) dirs return $ concat (foundFiles : foundFilesInDirs) -- >>> hasExtension [".htm", ".html"] "index.html" -- True -- >>> hasExtension [".htm", ".html"] "index.php.html" -- True -- >>> hasExtension [".htm", ".html"] "index.php" -- False -- >>> hasExtension [] "index.html" -- False -- >>> hasExtension [".htm", ".html"] "html" -- False hasExtension :: [String] -> FilePath -> Bool hasExtension extensions path = (takeExtension path) `elem` extensions