diff options
Diffstat (limited to 'hs/src/Files.hs')
-rw-r--r-- | hs/src/Files.hs | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/hs/src/Files.hs b/hs/src/Files.hs new file mode 100644 index 0000000..20554c1 --- /dev/null +++ b/hs/src/Files.hs @@ -0,0 +1,65 @@ +module Files +( mkdirP +, fileTree +, isFiletype +, copyFiles +) where + +import System.Directory hiding (isSymbolicLink) +import System.Posix.Files + ( FileStatus + , getFileStatus + , isBlockDevice + , isCharacterDevice + , isDirectory + , isNamedPipe + , isRegularFile + , isSocket + , isSymbolicLink + ) +import System.FilePath + ( joinPath + , takeExtension + , (</>) + ) + +mkdirP = createDirectoryIfMissing True + +fmt :: FileStatus -> String +fmt st | isBlockDevice st = "block" + | isCharacterDevice st = "char" + | isNamedPipe st = "pipe" + | isRegularFile st = "regular" + | isDirectory st = "directory" + | isSymbolicLink st = "symlink" + | isSocket st = "socket" + | otherwise = "UNKNOWN" + +instance Show FileStatus where + show st = fmt st + +fileTree :: [FilePath] -> IO [(FileStatus, [FilePath])] +fileTree base = do + items <- listDirectory (joinPath base) + concat <$> + mapM (\entry -> do + let here = base <> [entry] + let path = joinPath here + st <- getFileStatus path + let d = (st, here) + if isDirectory st + then (d :) <$> fileTree here + else return [ d ] + ) items + +isFiletype :: String -> FileStatus -> [FilePath] -> Bool +isFiletype extension st path + = isRegularFile st && (takeExtension . last $ path) == ('.' : extension) + +copyFile' :: FilePath -> FileStatus -> [FilePath] -> IO () +copyFile' dest st path + | isDirectory st = createDirectoryIfMissing True (dest </> (joinPath $ tail path)) + | otherwise = copyFile (joinPath path) $ dest </> (joinPath $ tail path) + +copyFiles :: FilePath -> [(FileStatus, [FilePath])] -> IO () +copyFiles dest = mapM_ (uncurry $ copyFile' dest) |