module Static.Resources.Generation
(generateResources)
where
import Control.Monad
import Data.Functor
import Data.Hash.MD5
import Data.Time
import Static.Resources.Types
import System.Process
generateAgregatedResourceTypeContent :: String -> ResourceType -> ResourceSet -> IO String
generateAgregatedResourceTypeContent dir rt rs = do
let files = map path $ filterByType (== rt) rs
s <- forM files $ \p -> readFile $ dir ++ "/" ++ p
return $ (concat s)
generateAgregatedCSSFile :: String -> ResourceSet -> IO FilePath
generateAgregatedCSSFile dir rs = do
c <- generateAgregatedResourceTypeContent dir CSS rs
let fn = (name rs) ++ "-" ++ (md5s $ Str $ c) ++ ".css"
writeFile (dir ++ "/" ++ fn) c
return fn
generateAgregatedLESSFile :: String -> ResourceSet -> IO FilePath
generateAgregatedLESSFile dir rs = do
let files = map path $ filterByType (== LESS) rs
c <- fmap concat $ forM files $ \file ->
readProcess "lessc" [dir ++ "/" ++ file] ""
let fn = name rs ++ "-" ++ md5s (Str c) ++ ".less.css"
writeFile (dir ++ "/" ++ fn) c
return fn
generateSeparateLESSFiles :: String -> ResourceSet -> IO [FilePath]
generateSeparateLESSFiles dir rs = do
forM (map path (filterByType (== LESS) rs)) $ \file -> do
contents <- readProcess "lessc" [dir ++ "/" ++ file] ""
let fn = file ++ ".css"
writeFile (dir ++ "/" ++ fn) contents
return fn
generateAgregatedJSFile :: String -> ResourceSet -> IO FilePath
generateAgregatedJSFile dir rs = do
c <- generateAgregatedResourceTypeContent dir JS rs
let fn = (name rs) ++ "-" ++ (md5s $ Str $ c) ++ ".js"
writeFile (dir ++ "/" ++ fn) c
return fn
generateResources :: ImportType -> String -> ResourceSpec -> FilePath -> IO ResourceSetsForImport
generateResources it dir spec pathPrefix =
liftM2 ResourceSetsForImport (forM (sets spec) (generateResourcesForSet it dir pathPrefix)) getCurrentTime
generateResourcesForSet :: ImportType -> String -> String -> ResourceSet -> IO ResourceSetForImport
generateResourcesForSet Development dir pathPrefix rs = do
lessF <- generateSeparateLESSFiles dir rs
return $ ResourceSetForImport {
set = rs
, cssFiles = prefixize (filterByType (== CSS) rs)
, jsFiles = prefixize (filterByType (\t -> t == JS || t == JSX) rs)
, lessFiles = map (appendPath pathPrefix) lessF
}
where prefixize = map (appendPath pathPrefix . path)
generateResourcesForSet Production dir pathPrefix rs = do
cssF <- generateAgregatedCSSFile dir rs
lessF <- generateAgregatedLESSFile dir rs
jsF <- generateAgregatedJSFile dir rs
return $ ResourceSetForImport {
set = rs
, cssFiles = prefixize [cssF]
, jsFiles = prefixize (jsF : (path <$> filterByType (== JSX) rs))
, lessFiles = prefixize [lessF]
}
where prefixize = map (appendPath pathPrefix)
appendPath :: String -> String -> String
appendPath left right = reverse (strip (reverse left)) ++ "/" ++ strip right
where strip = dropWhile (=='/')