summaryrefslogtreecommitdiff
path: root/hs/src/Files.hs
blob: bddcad645ed6039cf0c0efe4db6497d32493bb74 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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 = fmt

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 p
    | otherwise      = copyFile (joinPath path)      p
    where p = dest </> joinPath (tail path)

copyFiles :: FilePath -> [(FileStatus, [FilePath])] -> IO ()
copyFiles dest = mapM_ (uncurry $ copyFile' dest)