hakyll/src/Hakyll/Core/Compiler.hs

162 lines
5.8 KiB
Haskell
Raw Normal View History

2012-11-13 16:31:03 +00:00
--------------------------------------------------------------------------------
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}
2010-12-25 17:15:44 +00:00
module Hakyll.Core.Compiler
( Compiler
2010-12-29 21:59:38 +00:00
, getIdentifier
2010-12-30 20:18:55 +00:00
, getRoute
2011-02-06 17:32:09 +00:00
, getRouteFor
2012-11-13 22:59:49 +00:00
, getMetadata
, getMetadataFor
2012-11-10 17:11:46 +00:00
, getResourceBody
2010-12-29 21:59:38 +00:00
, getResourceString
2011-05-06 08:28:35 +00:00
, getResourceLBS
2011-09-19 21:08:40 +00:00
, getResourceWith
2010-12-25 17:15:44 +00:00
, require
2010-12-30 09:02:25 +00:00
, requireAll
, cached
2011-01-17 21:43:44 +00:00
, unsafeCompiler
2012-11-13 16:31:03 +00:00
, logCompiler
2011-02-21 12:02:35 +00:00
, timedCompiler
2010-12-25 17:15:44 +00:00
) where
2010-12-29 21:59:38 +00:00
2012-11-13 16:31:03 +00:00
--------------------------------------------------------------------------------
2012-11-13 22:59:49 +00:00
import Control.Applicative ((<$>))
import Data.Binary (Binary)
import Data.ByteString.Lazy (ByteString)
import Data.Typeable (Typeable)
import Prelude hiding (id, (.))
import System.Environment (getProgName)
2011-01-04 10:13:08 +00:00
2011-01-07 11:12:13 +00:00
2012-11-13 16:31:03 +00:00
--------------------------------------------------------------------------------
import Hakyll.Core.Compiler.Internal
import Hakyll.Core.Compiler.Require
2012-11-13 22:59:49 +00:00
import Hakyll.Core.Dependencies
2012-11-13 16:31:03 +00:00
import Hakyll.Core.Identifier
import Hakyll.Core.Logger
2012-11-13 22:59:49 +00:00
import Hakyll.Core.Metadata
2012-11-13 16:31:03 +00:00
import Hakyll.Core.ResourceProvider
import Hakyll.Core.Routes
2012-11-13 22:59:49 +00:00
import qualified Hakyll.Core.Store as Store
2012-11-13 16:31:03 +00:00
import Hakyll.Core.Writable
2011-01-07 11:12:13 +00:00
2012-11-13 16:31:03 +00:00
--------------------------------------------------------------------------------
2010-12-30 20:18:55 +00:00
-- | Get the identifier of the item that is currently being compiled
2012-11-13 16:31:03 +00:00
getIdentifier :: Compiler Identifier
getIdentifier = compilerIdentifier <$> compilerAsk
2010-12-30 20:18:55 +00:00
2012-11-13 16:31:03 +00:00
--------------------------------------------------------------------------------
2010-12-30 20:18:55 +00:00
-- | Get the route we are using for this item
2012-11-12 15:10:06 +00:00
getRoute :: Compiler (Maybe FilePath)
2012-11-13 16:31:03 +00:00
getRoute = getIdentifier >>= getRouteFor
2011-02-06 17:32:09 +00:00
2012-11-13 16:31:03 +00:00
--------------------------------------------------------------------------------
2011-02-06 17:32:09 +00:00
-- | Get the route for a specified item
2012-11-13 16:31:03 +00:00
getRouteFor :: Identifier -> Compiler (Maybe FilePath)
getRouteFor identifier = do
routes <- compilerRoutes <$> compilerAsk
2011-02-03 15:07:49 +00:00
return $ runRoutes routes identifier
2010-12-29 21:59:38 +00:00
2012-11-10 17:11:46 +00:00
2012-11-13 22:59:49 +00:00
--------------------------------------------------------------------------------
getMetadata :: Compiler Metadata
getMetadata = getIdentifier >>= getMetadataFor
--------------------------------------------------------------------------------
getMetadataFor :: Identifier -> Compiler Metadata
getMetadataFor identifier = do
provider <- compilerProvider <$> compilerAsk
compilerTell [IdentifierDependency identifier]
compilerUnsafeIO $ resourceMetadata provider identifier
2012-11-10 17:11:46 +00:00
--------------------------------------------------------------------------------
-- | Get the body of the underlying resource
2012-11-12 15:10:06 +00:00
getResourceBody :: Compiler String
2012-11-10 17:11:46 +00:00
getResourceBody = getResourceWith resourceBody
--------------------------------------------------------------------------------
2010-12-30 20:18:55 +00:00
-- | Get the resource we are compiling as a string
2012-11-12 15:10:06 +00:00
getResourceString :: Compiler String
2012-11-10 17:11:46 +00:00
getResourceString = getResourceWith $ const resourceString
2011-05-06 08:28:35 +00:00
2012-11-10 17:11:46 +00:00
--------------------------------------------------------------------------------
2011-05-06 08:28:35 +00:00
-- | Get the resource we are compiling as a lazy bytestring
--
2012-11-12 15:10:06 +00:00
getResourceLBS :: Compiler ByteString
2012-11-10 17:11:46 +00:00
getResourceLBS = getResourceWith $ const resourceLBS
2011-05-06 08:28:35 +00:00
2012-11-10 17:11:46 +00:00
--------------------------------------------------------------------------------
2011-05-06 08:28:35 +00:00
-- | Overloadable function for 'getResourceString' and 'getResourceLBS'
2012-11-13 16:31:03 +00:00
getResourceWith :: (ResourceProvider -> Identifier -> IO a) -> Compiler a
getResourceWith reader = do
provider <- compilerProvider <$> compilerAsk
id' <- compilerIdentifier <$> compilerAsk
let filePath = toFilePath id'
if resourceExists provider id'
then compilerUnsafeIO $ reader provider id'
else compilerThrow $ error' filePath
where
2012-11-13 16:31:03 +00:00
error' fp = "Hakyll.Core.Compiler.getResourceWith: resource " ++
show fp ++ " not found"
2011-01-18 22:58:29 +00:00
2012-11-13 16:31:03 +00:00
--------------------------------------------------------------------------------
cached :: (Binary a, Typeable a, Writable a)
=> String
2012-11-12 15:10:06 +00:00
-> Compiler a
-> Compiler a
2012-11-13 16:31:03 +00:00
cached name compiler = do
logger <- compilerLogger <$> compilerAsk
id' <- compilerIdentifier <$> compilerAsk
store <- compilerStore <$> compilerAsk
provider <- compilerProvider <$> compilerAsk
modified <- compilerUnsafeIO $ resourceModified provider id'
compilerUnsafeIO $ report logger $
"Checking cache: " ++ if modified then "modified" else "OK"
if modified
2012-11-13 16:31:03 +00:00
then do
x <- compiler
compilerUnsafeIO $ Store.set store [name, show id'] x
return x
else do
x <- compilerUnsafeIO $ Store.get store [name, show id']
progName <- compilerUnsafeIO getProgName
case x of Store.Found x' -> return x'
_ -> compilerThrow (error' progName)
where
error' progName =
"Hakyll.Core.Compiler.cached: Cache corrupt! " ++
"Try running: " ++ progName ++ " clean"
2011-01-17 21:43:44 +00:00
2011-02-09 12:02:28 +00:00
2012-11-13 16:31:03 +00:00
--------------------------------------------------------------------------------
unsafeCompiler :: IO a -> Compiler a
unsafeCompiler = compilerUnsafeIO
2011-02-25 13:36:34 +00:00
2012-11-13 16:31:03 +00:00
--------------------------------------------------------------------------------
-- | Compiler for debugging purposes
logCompiler :: String -> Compiler ()
logCompiler msg = do
logger <- compilerLogger <$> compilerAsk
compilerUnsafeIO $ report logger msg
2012-02-13 20:44:38 +00:00
2012-11-13 16:31:03 +00:00
--------------------------------------------------------------------------------
-- | Log and time a compiler
timedCompiler :: String -- ^ Message
-> Compiler a -- ^ Compiler to time
-> Compiler a -- ^ Resulting compiler
timedCompiler msg compiler = Compiler $ \r ->
timed (compilerLogger r) msg $ unCompiler compiler r