module Development.Duplo.Static where
import Control.Applicative ((<$>))
import Control.Lens hiding (Action)
import Control.Monad (filterM, zipWithM_)
import Data.List (nub, transpose)
import Development.Duplo.FileList (Copy, collapseFileLists,
makeFile, makeFiles, toCopies)
import qualified Development.Duplo.FileList as FileList (filePath)
import qualified Development.Duplo.Types.Config as TC
import Development.Duplo.Utilities (createIntermediaryDirectories,
createPathDirectories,
getDirectoryFiles,
headerPrintSetter, logStatus)
import Development.Shake hiding (getDirectoryFiles)
import Development.Shake.FilePath ((</>))
import System.FilePath.Posix (makeRelative, splitDirectories,
splitExtension)
build :: TC.BuildConfig
-> [FilePath]
-> Action ()
build config outs = do
let targetPath = config ^. TC.targetPath
let assetsPath = config ^. TC.assetsPath
let depsPath = config ^. TC.depsPath
let devPath = config ^. TC.devPath
let devAssetPath = devPath </> "assets"
let testAssetPath = config ^. TC.duploPath </> "etc/test"
let filesRel = fmap (makeRelative targetPath) outs
let assetFiles = makeFiles assetsPath filesRel
depAssetDirs <- getDirectoryDirs depsPath
let depAssetPaths = [ base </> dep </> src </> "assets"
| src <- ["app"]
, base <- [depsPath]
, dep <- depAssetDirs
]
let depAssetFiles = [ makeFile base file
| base <- depAssetPaths
, file <- filesRel
]
let devFiles = makeFiles devAssetPath filesRel
let testFiles = makeFiles testAssetPath filesRel
let possibleFiles = transpose [devFiles, testFiles, assetFiles, depAssetFiles]
cleanedFiles <- collapseFileLists possibleFiles
let targetIndex = targetPath </> "index.html"
let isTargetIndex file = targetIndex /= file ^. FileList.filePath
let filesLessIndex = filter isTargetIndex cleanedFiles
let (froms, tos) = unzip $ toCopies targetPath filesLessIndex
let repeat' = replicate $ length froms
let messages = transpose [ repeat' "Copying "
, froms
, repeat' " to "
, tos
]
mapM_ (putNormal . concat) messages
mapM_ createIntermediaryDirectories tos
zipWithM_ copyFileChanged froms tos
deps :: TC.BuildConfig
-> Action ()
deps config = do
liftIO $ logStatus headerPrintSetter "Copying static files"
let assetsPath = config ^. TC.assetsPath
let depsPath = config ^. TC.depsPath
let targetPath = config ^. TC.targetPath
let devPath = config ^. TC.devPath
let devAssetsPath = devPath </> "assets/"
let testAssetsPath = config ^. TC.duploPath </> "etc/test"
createPathDirectories [assetsPath, depsPath, targetPath, devAssetsPath]
assetFiles <- getDirectoryFiles assetsPath ["//*"]
depAssetFiles <- getDepAssets depsPath
devFiles' <- getDirectoryFiles devAssetsPath ["//*"]
let devFiles = if TC.isInDev config then devFiles' else []
testFiles' <- getDirectoryFiles testAssetsPath ["vendor//*"]
let testFiles = if TC.isInTest config then testFiles' else []
let allFiles = nub $ concat [depAssetFiles, assetFiles, devFiles, testFiles]
let files = filter ("index.html" /=) allFiles
let getExt = snd . splitExtension
let getFilename = last . splitDirectories
let firstFilenameChar = head . getFilename
let onlyVisible = filter (('.' /=) . firstFilenameChar)
let staticFiles = onlyVisible files
let filesOut = fmap (targetPath ++) staticFiles
need filesOut
qualify :: TC.BuildConfig
-> FilePath
-> Maybe [FilePath]
qualify config path =
if targetPath ?== path
then Just [path]
else Nothing
where
targetPath = config ^. TC.targetPath ++ "/*"
getDepAssets :: FilePath -> Action [FilePath]
getDepAssets depsPath = do
depNames <- getDirectoryDirs depsPath
let depAssetDirs = fmap ((depsPath </>) . (</> "app/assets")) depNames
applicableDeps <- filterM doesDirectoryExist depAssetDirs
let assets = [ getDirectoryFiles dep ["//*"]
| dep <- applicableDeps
]
concat <$> sequence assets