module Development.Cake3.Utils.Find where
import Control.Applicative
import Control.Monad.Trans
import System.Directory
import System.IO.Unsafe (unsafeInterleaveIO)
import System.FilePath.Wrapper
import Development.Cake3
import Development.Cake3.Types
import Development.Cake3.Monad
filterExts :: [String] -> [File] -> [File]
filterExts exts files = filter (\f -> or $ map (isExt f) exts) files where
isExt f e = takeExtension f == (sureDot e)
sureDot [] = error "filterExt: empty extantion passed"
sureDot e@('.':cs) = e
sureDot e@(c:cs) = '.':e
getDirectoryContentsRecursive :: (MonadIO m) => File -> m [File]
getDirectoryContentsRecursive td@(FileT topdir) = map (td</>) `liftM` (liftIO $ recurseDirectories [""])
where
recurseDirectories :: [FilePath] -> IO [FilePath]
recurseDirectories [] = return []
recurseDirectories (dir:dirs) = unsafeInterleaveIO $ do
(files, dirs') <- collect [] [] =<< getDirectoryContents (topdir </> dir)
files' <- recurseDirectories (dirs' ++ dirs)
return (files ++ files')
where
collect files dirs' [] = return (reverse files, reverse dirs')
collect files dirs' (entry:entries) | ignore entry
= collect files dirs' entries
collect files dirs' (entry:entries) = do
let dirEntry = dir </> entry
isDirectory <- doesDirectoryExist (topdir </> dirEntry)
if isDirectory
then collect files (dirEntry:dirs') entries
else collect (dirEntry:files) dirs' entries
ignore ['.'] = True
ignore ['.', '.'] = True
ignore _ = False