1--------------------------------------------------------------------------------
2{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3{-# LANGUAGE ScopedTypeVariables #-}
4module Hakyll.Core.Compiler
7 , getUnderlyingExtension
18 , Internal.loadSnapshot
20 , Internal.loadSnapshotBody
22 , Internal.loadAllSnapshots
30--------------------------------------------------------------------------------
31import Control.Monad (when)
32import Data.Binary (Binary)
33import Data.ByteString.Lazy (ByteString)
34import Data.Typeable (Typeable)
35import System.Environment (getProgName)
36import System.FilePath (takeExtension)
39--------------------------------------------------------------------------------
40import Hakyll.Core.Compiler.Internal
41import qualified Hakyll.Core.Compiler.Require as Internal
42import Hakyll.Core.Dependencies
43import Hakyll.Core.Identifier
44import Hakyll.Core.Item
45import Hakyll.Core.Logger as Logger
46import Hakyll.Core.Provider
47import Hakyll.Core.Routes
48import qualified Hakyll.Core.Store as Store
51--------------------------------------------------------------------------------
52-- | Get the underlying identifier.
53getUnderlying :: Compiler Identifier
54getUnderlying = compilerUnderlying <$> compilerAsk
57--------------------------------------------------------------------------------
58-- | Get the extension of the underlying identifier. Returns something like
60getUnderlyingExtension :: Compiler String
61getUnderlyingExtension = takeExtension . toFilePath <$> getUnderlying
64--------------------------------------------------------------------------------
65makeItem :: a -> Compiler (Item a)
67 identifier <- getUnderlying
68 return $ Item identifier x
71--------------------------------------------------------------------------------
72-- | Get the route for a specified item
73getRoute :: Identifier -> Compiler (Maybe FilePath)
74getRoute identifier = do
75 provider <- compilerProvider <$> compilerAsk
76 routes <- compilerRoutes <$> compilerAsk
77 -- Note that this makes us dependend on that identifier: when the metadata
78 -- of that item changes, the route may change, hence we have to recompile
79 (mfp, um) <- compilerUnsafeIO $ runRoutes routes provider identifier
80 when um $ compilerTellDependencies [IdentifierDependency identifier]
84--------------------------------------------------------------------------------
85-- | Get the full contents of the matched source file as a string,
86-- but without metadata preamble, if there was one.
87getResourceBody :: Compiler (Item String)
88getResourceBody = getResourceWith resourceBody
91--------------------------------------------------------------------------------
92-- | Get the full contents of the matched source file as a string.
93getResourceString :: Compiler (Item String)
94getResourceString = getResourceWith resourceString
97--------------------------------------------------------------------------------
98-- | Get the full contents of the matched source file as a lazy bytestring.
99getResourceLBS :: Compiler (Item ByteString)
100getResourceLBS = getResourceWith resourceLBS
103--------------------------------------------------------------------------------
104-- | Get the file path of the resource we are compiling
105getResourceFilePath :: Compiler FilePath
106getResourceFilePath = do
107 provider <- compilerProvider <$> compilerAsk
108 id' <- compilerUnderlying <$> compilerAsk
109 return $ resourceFilePath provider id'
112--------------------------------------------------------------------------------
113-- | Overloadable function for 'getResourceString' and 'getResourceLBS'
114getResourceWith :: (Provider -> Identifier -> IO a) -> Compiler (Item a)
115getResourceWith reader = do
116 provider <- compilerProvider <$> compilerAsk
117 id' <- compilerUnderlying <$> compilerAsk
118 let filePath = toFilePath id'
119 if resourceExists provider id'
120 then compilerUnsafeIO $ Item id' <$> reader provider id'
121 else fail $ error' filePath
123 error' fp = "Hakyll.Core.Compiler.getResourceWith: resource " ++
124 show fp ++ " not found"
127--------------------------------------------------------------------------------
128-- | Save a snapshot of the item. This function returns the same item, which
129-- convenient for building '>>=' chains.
130saveSnapshot :: (Binary a, Typeable a)
131 => Internal.Snapshot -> Item a -> Compiler (Item a)
132saveSnapshot snapshot item = do
133 store <- compilerStore <$> compilerAsk
134 logger <- compilerLogger <$> compilerAsk
135 compilerUnsafeIO $ do
136 Logger.debug logger $ "Storing snapshot: " ++ snapshot
137 Internal.saveSnapshot store snapshot item
139 -- Signal that we saved the snapshot.
140 Compiler $ \_ -> return $ CompilerSnapshot snapshot (return item)
143--------------------------------------------------------------------------------
144cached :: (Binary a, Typeable a)
148cached name compiler = do
149 id' <- compilerUnderlying <$> compilerAsk
150 store <- compilerStore <$> compilerAsk
151 provider <- compilerProvider <$> compilerAsk
152 let modified = resourceModified provider id'
156 compilerUnsafeIO $ Store.set store [name, show id'] x
159 compilerTellCacheHits 1
160 x <- compilerUnsafeIO $ Store.get store [name, show id']
161 progName <- compilerUnsafeIO getProgName
162 case x of Store.Found x' -> return x'
163 _ -> fail $ error' progName
166 "Hakyll.Core.Compiler.cached: Cache corrupt! " ++
167 "Try running: " ++ progName ++ " clean"
170--------------------------------------------------------------------------------
171unsafeCompiler :: IO a -> Compiler a
172unsafeCompiler = compilerUnsafeIO
175--------------------------------------------------------------------------------
176-- | Compiler for debugging purposes
177debugCompiler :: String -> Compiler ()
178debugCompiler msg = do
179 logger <- compilerLogger <$> compilerAsk
180 compilerUnsafeIO $ Logger.debug logger msg
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list