1-- | A Compiler manages targets and dependencies between targets.
3{-# LANGUAGE GeneralizedNewtypeDeriving #-}
4module Hakyll.Core.Compiler
16import Prelude hiding ((.), id)
17import Control.Arrow ((>>>))
18import Control.Applicative ((<$>))
19import Control.Monad.Reader (ask)
20import Control.Monad.Trans (liftIO)
21import Control.Category (Category, (.))
22import Data.Maybe (fromMaybe)
24import Data.Binary (Binary)
25import Data.Typeable (Typeable)
27import Hakyll.Core.Identifier
28import Hakyll.Core.Identifier.Pattern
29import Hakyll.Core.CompiledItem
30import Hakyll.Core.Writable
31import Hakyll.Core.ResourceProvider
32import Hakyll.Core.Compiler.Internal
33import Hakyll.Core.Store
34import Hakyll.Core.Rules
36-- | Run a compiler, yielding the resulting target and it's dependencies. This
37-- version of 'runCompilerJob' also stores the result
39runCompiler :: Compiler () CompileRule -- ^ Compiler to run
40 -> Identifier -- ^ Target identifier
41 -> ResourceProvider -- ^ Resource provider
42 -> Maybe FilePath -- ^ Route
44 -> Bool -- ^ Was the resource modified?
45 -> IO CompileRule -- ^ Resulting item
46runCompiler compiler identifier provider route' store modified = do
47 -- Run the compiler job
48 result <- runCompilerJob compiler identifier provider route' store modified
52 -- In case we compiled an item, we will store a copy in the cache first,
53 -- before we return control. This makes sure the compiled item can later
54 -- be accessed by e.g. require.
55 CompileRule (CompiledItem x) ->
56 storeSet store "Hakyll.Core.Compiler.runCompiler" identifier x
58 -- Otherwise, we do nothing here
63-- | Get the identifier of the item that is currently being compiled
65getIdentifier :: Compiler a Identifier
66getIdentifier = fromJob $ const $ CompilerM $ compilerIdentifier <$> ask
68-- | Get the route we are using for this item
70getRoute :: Compiler a (Maybe FilePath)
71getRoute = fromJob $ const $ CompilerM $ compilerRoute <$> ask
73-- | Get the resource we are compiling as a string
75getResourceString :: Compiler a String
76getResourceString = getIdentifier >>> getResourceString'
78 getResourceString' = fromJob $ \id' -> CompilerM $ do
79 provider <- compilerResourceProvider <$> ask
80 liftIO $ resourceString provider id'
82-- | Auxiliary: get a dependency
84getDependency :: (Binary a, Writable a, Typeable a)
85 => Identifier -> CompilerM a
86getDependency identifier = CompilerM $ do
87 store <- compilerStore <$> ask
88 fmap (fromMaybe error') $ liftIO $
89 storeGet store "Hakyll.Core.Compiler.runCompiler" identifier
91 error' = error $ "Hakyll.Core.Compiler.getDependency: "
93 ++ " not found in the cache, the cache might be corrupted"
95-- | Wait until another compiler has finished before running this compiler
97waitFor :: Identifier -> Compiler a a
98waitFor = fromDependencies . const . return
100-- | Require another target. Using this function ensures automatic handling of
103require :: (Binary a, Typeable a, Writable a)
107require identifier f =
108 waitFor identifier >>> fromJob require'
111 y <- getDependency identifier
114-- | Require a number of targets. Using this function ensures automatic handling
117requireAll :: (Binary a, Typeable a, Writable a)
121requireAll pattern f =
122 fromDependencies getDeps >>> fromJob requireAll'
124 getDeps = matches pattern . resourceList
125 requireAll' x = CompilerM $ do
126 deps <- getDeps . compilerResourceProvider <$> ask
127 items <- mapM (unCompilerM . getDependency) deps
130cached :: (Binary a, Typeable a, Writable a)
134cached name (Compiler d j) = Compiler d $ const $ CompilerM $ do
135 identifier <- compilerIdentifier <$> ask
136 store <- compilerStore <$> ask
137 modified <- compilerResourceModified <$> ask
139 show identifier ++ ": " ++ if modified then "MODIFIED" else "OK"
141 then do v <- unCompilerM $ j ()
142 liftIO $ storeSet store name identifier v
144 else do v <- liftIO $ storeGet store name identifier
145 case v of Just v' -> return v'
148 error' = error "Hakyll.Core.Compiler.cached: Cache corrupt!"
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