module Development.Duplo.Static where
import Control.Applicative ((<$>))
import Control.Lens hiding (Action)
import Control.Monad (zipWithM_, filterM)
import Data.List (transpose, nub)
import Development.Duplo.FileList (makeFile, makeFiles, toCopies, collapseFileLists, Copy)
import Development.Duplo.Utilities (logStatus, headerPrintSetter, createIntermediaryDirectories, createPathDirectories, getDirectoryFiles)
import Development.Shake hiding (getDirectoryFiles)
import Development.Shake.FilePath ((</>))
import System.FilePath.Posix (splitExtension, splitDirectories, makeRelative)
import qualified Development.Duplo.FileList as FileList (filePath)
import qualified Development.Duplo.Types.Config as TC
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