module Static.Resources
(
htmlImportList
, getResourceSetsForImport
, cleanResourceFiles
, ResourceSpec
, parseSpec
, check
, ImportType(..)
, ResourceSetsForImport(..)
, generateResources
, resourcesMTime
) where
import Static.Resources.Types
import Static.Resources.Spec
import Static.Resources.Checker
import Static.Resources.Generation
import Static.Resources.Import
import Control.Monad
import Control.Monad.Error
import Data.List
import Data.Maybe
import System.Directory
import System.FilePath
import System.Time
getResourceSetsForImport :: ImportType
-> FilePath
-> FilePath
-> IO (Either String ResourceSetsForImport)
getResourceSetsForImport it fp pathPrefix = do
spec <- parseSpec fp
withTemporaryCurrentDirectory (takeDirectory fp) $ do
cleanResourceFiles spec
res <- runErrorT $ do
when (null $ sets spec) $ throwError "No resource sets are defined"
checkRes <- lift $ check spec
either (throwError . ("Error while checking spec. Error : " ++))
(const (return ()))
checkRes
lift $ generateResources it spec pathPrefix
case res of
Left s -> putStrLn $ "Static resource generation failed. " ++ s
Right (ResourceSetsForImport rs _) ->
putStrLn $ "Static resource generation done. Generated " ++
show (length rs) ++ " sets."
return res
cleanResourceFiles :: ResourceSpec -> IO ()
cleanResourceFiles = getGeneratedFiles >=> mapM_ removeFile
getGeneratedFiles :: ResourceSpec -> IO [FilePath]
getGeneratedFiles spec = do
mainFiles <- fmap (filter (\fn -> any (`isPrefixOf` fn) (map name (sets spec)) && isStaticResourceFile fn))
(getDirectoryContents ".")
let potentialCompiledLessLocalFiles = map (\r -> (path r) ++ ".css") $ filter (\r -> LESS == rtype r) $ concatMap resources $ sets spec
compiledLessLocalFiles <- forM potentialCompiledLessLocalFiles $ \fn -> do
exists <- doesFileExist fn
if (exists)
then return $ Just fn
else return $ Nothing
return $ mainFiles ++ (map fromJust $ filter isJust compiledLessLocalFiles)
withTemporaryCurrentDirectory :: FilePath -> IO a -> IO a
withTemporaryCurrentDirectory dir m = do
currrent <- getCurrentDirectory
setCurrentDirectory dir
x <- m
setCurrentDirectory currrent
return x
resourcesMTime :: FilePath -> IO ClockTime
resourcesMTime fp = resourcesMTime' (takeDirectory fp)
resourcesMTime' :: FilePath -> IO ClockTime
resourcesMTime' fp = do
fs <- getDirectoryContents fp
fmap maximum $ forM fs $ \f -> do
isDirectory <- doesDirectoryExist (fp ++ "/" ++f)
case ('.' == last f, isDirectory, isStaticResourceFile f) of
(True,_,_) -> return (TOD 0 0)
(_,True,_) -> resourcesMTime' $ fp ++ "/" ++f
(_,_,True) -> getModificationTime $ fp ++ "/" ++ f
(_,_,_) -> return (TOD 0 0)