1--------------------------------------------------------------------------------
2-- | Internally used compiler module
4{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5module Hakyll.Core.Compiler.Internal
22 , compilerTellDependencies
23 , compilerTellCacheHits
27--------------------------------------------------------------------------------
28import Control.Applicative (Alternative (..),
29 Applicative (..), (<$>))
30import Control.Exception (SomeException, handle)
31import Data.Monoid (Monoid (..))
33import qualified Data.Set as S
36--------------------------------------------------------------------------------
37import Hakyll.Core.Dependencies
38import Hakyll.Core.Identifier
39import Hakyll.Core.Identifier.Pattern
40import Hakyll.Core.Logger
41import Hakyll.Core.Metadata
42import Hakyll.Core.Provider
43import Hakyll.Core.Routes
44import Hakyll.Core.Store
47--------------------------------------------------------------------------------
48-- | Environment in which a compiler runs
49data CompilerRead = CompilerRead
50 { -- | Underlying identifier
51 compilerUnderlying :: Identifier
52 , -- | Resource provider
53 compilerProvider :: Provider
54 , -- | List of all known identifiers
55 compilerUniverse :: Set Identifier
57 compilerRoutes :: Routes
59 compilerStore :: Store
61 compilerLogger :: Logger
65--------------------------------------------------------------------------------
66data CompilerWrite = CompilerWrite
67 { compilerDependencies :: [Dependency]
68 , compilerCacheHits :: Int
72--------------------------------------------------------------------------------
73instance Monoid CompilerWrite where
74 mempty = CompilerWrite [] 0
75 mappend (CompilerWrite d1 h1) (CompilerWrite d2 h2) =
76 CompilerWrite (d1 ++ d2) (h1 + h2)
79--------------------------------------------------------------------------------
80data CompilerResult a where
81 CompilerDone :: a -> CompilerWrite -> CompilerResult a
82 CompilerError :: String -> CompilerResult a
83 CompilerRequire :: Identifier -> Compiler a -> CompilerResult a
86--------------------------------------------------------------------------------
87-- | A monad which lets you compile items and takes care of dependency tracking
89newtype Compiler a = Compiler
90 { unCompiler :: CompilerRead -> IO (CompilerResult a)
94--------------------------------------------------------------------------------
95instance Functor Compiler where
96 fmap f (Compiler c) = Compiler $ \r -> do
99 CompilerDone x w -> CompilerDone (f x) w
100 CompilerError e -> CompilerError e
101 CompilerRequire i c' -> CompilerRequire i (fmap f c')
105--------------------------------------------------------------------------------
106instance Monad Compiler where
107 return x = Compiler $ \_ -> return $ CompilerDone x mempty
108 {-# INLINE return #-}
110 Compiler c >>= f = Compiler $ \r -> do
113 CompilerDone x w -> do
114 res' <- unCompiler (f x) r
115 return $ case res' of
116 CompilerDone y w' -> CompilerDone y (w `mappend` w')
117 CompilerError e -> CompilerError e
118 CompilerRequire i c' -> CompilerRequire i $ do
119 compilerTell w -- Save dependencies!
122 CompilerError e -> return $ CompilerError e
123 CompilerRequire i c' -> return $ CompilerRequire i $ c' >>= f
127--------------------------------------------------------------------------------
128instance Applicative Compiler where
132 f <*> x = f >>= \f' -> fmap f' x
136--------------------------------------------------------------------------------
137instance MonadMetadata Compiler where
138 getMetadata = compilerGetMetadata
139 getMatches = compilerGetMatches
142--------------------------------------------------------------------------------
143runCompiler :: Compiler a -> CompilerRead -> IO (CompilerResult a)
144runCompiler compiler read' = handle handler $ unCompiler compiler read'
146 handler :: SomeException -> IO (CompilerResult a)
147 handler e = return $ CompilerError $ show e
150--------------------------------------------------------------------------------
151instance Alternative Compiler where
152 empty = compilerThrow "Hakyll.Core.Compiler.Internal: empty alternative"
153 x <|> y = compilerCatch x (\_ -> y)
157--------------------------------------------------------------------------------
158compilerAsk :: Compiler CompilerRead
159compilerAsk = Compiler $ \r -> return $ CompilerDone r mempty
160{-# INLINE compilerAsk #-}
163--------------------------------------------------------------------------------
164compilerTell :: CompilerWrite -> Compiler ()
165compilerTell deps = Compiler $ \_ -> return $ CompilerDone () deps
166{-# INLINE compilerTell #-}
169--------------------------------------------------------------------------------
170compilerThrow :: String -> Compiler a
171compilerThrow e = Compiler $ \_ -> return $ CompilerError e
172{-# INLINE compilerThrow #-}
175--------------------------------------------------------------------------------
176compilerCatch :: Compiler a -> (String -> Compiler a) -> Compiler a
177compilerCatch (Compiler x) f = Compiler $ \r -> do
180 CompilerError e -> unCompiler (f e) r
182{-# INLINE compilerCatch #-}
185--------------------------------------------------------------------------------
186-- | Put the result back in a compiler
187compilerResult :: CompilerResult a -> Compiler a
188compilerResult x = Compiler $ \_ -> return x
189{-# INLINE compilerResult #-}
192--------------------------------------------------------------------------------
193compilerUnsafeIO :: IO a -> Compiler a
194compilerUnsafeIO io = Compiler $ \_ -> do
196 return $ CompilerDone x mempty
197{-# INLINE compilerUnsafeIO #-}
200--------------------------------------------------------------------------------
201compilerTellDependencies :: [Dependency] -> Compiler ()
202compilerTellDependencies ds = compilerTell mempty {compilerDependencies = ds}
203{-# INLINE compilerTellDependencies #-}
206--------------------------------------------------------------------------------
207compilerTellCacheHits :: Int -> Compiler ()
208compilerTellCacheHits ch = compilerTell mempty {compilerCacheHits = ch}
209{-# INLINE compilerTellCacheHits #-}
212--------------------------------------------------------------------------------
213compilerGetMetadata :: Identifier -> Compiler Metadata
214compilerGetMetadata identifier = do
215 provider <- compilerProvider <$> compilerAsk
216 compilerTellDependencies [IdentifierDependency identifier]
217 compilerUnsafeIO $ resourceMetadata provider identifier
220--------------------------------------------------------------------------------
221compilerGetMatches :: Pattern -> Compiler [Identifier]
222compilerGetMatches pattern = do
223 universe <- compilerUniverse <$> compilerAsk
224 let matching = filterMatches pattern $ S.toList universe
225 compilerTellDependencies [PatternDependency pattern matching]
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