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
import System.Time
generateAgregatedResourceTypeContent :: ResourceType -> ResourceSet -> IO String
generateAgregatedResourceTypeContent rt rs = do
let files = map path $ filterByType (== rt) rs
s <- forM files $ \p -> readFile p
return $ (concat s)
generateAgregatedCSSFile :: ResourceSet -> IO FilePath
generateAgregatedCSSFile rs = do
t <- show <$> getCurrentTime
c <- generateAgregatedResourceTypeContent CSS rs
let fn = (name rs) ++ "-" ++ (md5s $ Str $ t) ++ ".css"
writeFile fn c
return fn
generateAgregatedLESSFile :: ResourceSet -> IO FilePath
generateAgregatedLESSFile rs = do
t <- show <$> getCurrentTime
let files = map path $ filterByType (== LESS) rs
c <- fmap concat $ forM files $ \file ->
readProcess "lessc" [file] ""
let fn = name rs ++ "-" ++ md5s (Str t) ++ ".less.css"
writeFile fn c
return fn
generateSeparateLESSFiles :: ResourceSet -> IO [FilePath]
generateSeparateLESSFiles rs = do
forM (map path (filterByType (== LESS) rs)) $ \file -> do
contents <- readProcess "lessc" [file] ""
let fn = file ++ ".css"
writeFile fn contents
return fn
generateAgregatedJSFile :: ResourceSet -> IO FilePath
generateAgregatedJSFile rs = do
t <- show <$> getCurrentTime
c <- generateAgregatedResourceTypeContent JS rs
let fn = (name rs) ++ "-" ++ (md5s $ Str $ t) ++ ".js"
writeFile fn c
return fn
generateResources :: ImportType -> ResourceSpec -> FilePath -> IO ResourceSetsForImport
generateResources it spec pathPrefix =
liftM2 ResourceSetsForImport (forM (sets spec) (generateResourcesForSet it pathPrefix)) getClockTime
generateResourcesForSet :: ImportType -> String -> ResourceSet -> IO ResourceSetForImport
generateResourcesForSet Development pathPrefix rs = do
lessF <- generateSeparateLESSFiles 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 pathPrefix rs = do
cssF <- generateAgregatedCSSFile rs
lessF <- generateAgregatedLESSFile rs
jsF <- generateAgregatedJSFile 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 (=='/')