duplo-1.6.9: src/Development/Duplo/FileList.hs
{-# LANGUAGE TemplateHaskell #-}
module Development.Duplo.FileList where
import Control.Lens hiding (Action)
import Control.Lens.TH (makeLenses)
import Control.Monad (liftM, msum)
import Data.Maybe (Maybe(..), catMaybes)
import Development.Shake
import Development.Shake.FilePath ((</>))
import System.FilePath.Posix (makeRelative)
data File = File { _filePath :: FilePath
, _fileBase :: FilePath
} deriving (Show)
type Copy = (FilePath, FilePath)
defaultFile :: File
defaultFile = File { _filePath = ""
, _fileBase = ""
}
makeLenses ''File
-- | Given a base and a list of relative paths, transform into file objects
makeFiles :: FilePath -> [FilePath] -> [File]
makeFiles = fmap . makeFile
-- | Given a base and a relative path, return a file record containing the
-- absolute path with the base
makeFile :: FilePath -> FilePath -> File
makeFile base relPath =
setPath absPath
where
constructor = defaultFile { _fileBase = base }
absPath = base </> relPath
setPath = (constructor &) . (filePath .~)
-- | Collapse lists of possible files and return the first file that exists
-- for each list
collapseFileLists :: [[File]] -> Action [File]
collapseFileLists = liftM catMaybes . mapM collapseFileList
-- | Given a list of possible files, reduce to a file that exists, or
-- nothing
collapseFileList :: [File] -> Action (Maybe File)
collapseFileList = liftM msum . mapM collapseFile
-- | Given a file, return itself if it exists
collapseFile :: File -> Action (Maybe File)
collapseFile file = do
let path = file ^. filePath
doesExist <- doesFileExist path
return $ if doesExist then Just file else Nothing
-- | Given an output path and a list of file objects, convert all files
-- objects to copy pairs. See `toCopy` for more information.
toCopies :: FilePath -> [File] -> [Copy]
toCopies base = fmap $ toCopy base
-- | Given an output path and a file object, return a copy pair whose to
-- path is relative to the output path in the same way as the provided file
-- object's path is relative to its base.
toCopy :: FilePath -> File -> Copy
toCopy targetBase file =
(from, to)
where
path = file ^. filePath
base = file ^. fileBase
relPath = makeRelative base path
from = path
to = targetBase </> relPath