on master help sign in
Track metadata dependencies

I had to prepend some Rules to global Rules set. This might be possible to replaced by a correct Store.set call. I also had to prepend some Compile rules.

commit712ffa39b5857fdc5cdae1db38a177267a430b11 authorAlexey Kreshchuk <akrsch@gmail.com> dateWed 16 Oct 2013, 01:39 (13 years ago) parenta6ae4eb
5 files changed+45−14
hakyll.cabal+1 src/Hakyll/Core/Metadata.hs+10 src/Hakyll/Core/Provider/Metadata.hs+8−12 src/Hakyll/Core/Rules/Default.hs+23 src/Hakyll/Core/Runtime.hs+3−2
hakyll.cabal+1
@@ -133,6 +133,7 @@ Library
133133 Hakyll.Core.Provider.Metadata
134134 Hakyll.Core.Provider.MetadataCache
135135 Hakyll.Core.Rules.Internal
136+ Hakyll.Core.Rules.Default
136137 Hakyll.Core.Runtime
137138 Hakyll.Core.Store
138139 Hakyll.Core.Util.File
src/Hakyll/Core/Metadata.hs+10
@@ -5,6 +5,7 @@ module Hakyll.Core.Metadata
55 , getMetadataField
66 , getMetadataField'
77 , makePatternDependency
8+ , metadataFiles
89 ) where
910
1011
@@ -12,6 +13,7 @@ module Hakyll.Core.Metadata
1213import Control.Monad (forM)
1314import Data.Map (Map)
1415import qualified Data.Map as M
16+import System.FilePath.Posix ((</>), takeDirectory)
1517
1618
1719--------------------------------------------------------------------------------
@@ -61,3 +63,11 @@ makePatternDependency :: MonadMetadata m => Pattern -> m Dependency
6163makePatternDependency pattern = do
6264 matches' <- getMatches pattern
6365 return $ PatternDependency pattern matches'
66+
67+--------------------------------------------------------------------------------
68+-- | Returns a list of all directory-wise metadata files, subdir first, global last
69+metadataFiles :: Identifier -> [Identifier]
70+metadataFiles = go . takeDirectory . toFilePath where
71+ go "." = [fromFilePath "metadata"]
72+ go dir = fromFilePath (dir </> "metadata") : go (takeDirectory dir)
73+
src/Hakyll/Core/Provider/Metadata.hs+8−12
@@ -44,7 +44,7 @@ loadMetadata p identifier = do
4444 Nothing -> return M.empty
4545 Just mi' -> loadMetadataFile $ resourceFilePath p mi'
4646
47− gmd <- loadGlobalMetadata p $ toFilePath identifier
47+ gmd <- loadGlobalMetadata p identifier
4848
4949 return (M.unions [md, emd, gmd], body)
5050 where
@@ -141,21 +141,17 @@ page = do
141141
142142--------------------------------------------------------------------------------
143143-- | Load directory-wise metadata
144−loadGlobalMetadata :: Provider -> FilePath -> IO (M.Map String String)
145−loadGlobalMetadata p fp = liftM M.fromList $ loadgm $ takeDirectory fp where
146− loadgm :: FilePath -> IO [(String, String)]
147− loadgm dir | dir == "." = return []
148− | otherwise = do
149− let mfp = fromFilePath $ combine dir "metadata"
150− md <- if resourceExists p mfp then loadOne mfp dir else return []
151− others <- loadgm (takeDirectory dir)
152− return $ others ++ md
153− loadOne mfp dir =
144+loadGlobalMetadata :: Provider -> Identifier -> IO Metadata
145+loadGlobalMetadata p fp = liftM M.fromList $ loadgm fp where
146+ loadgm :: Identifier -> IO [(String, String)]
147+ loadgm = liftM concat . mapM loadOne . reverse . filter (resourceExists p) . metadataFiles
148+ loadOne mfp =
154149 let path = resourceFilePath p mfp
150+ dir = takeDirectory $ toFilePath mfp
155151 -- TODO: It might be better to print warning and continue
156152 in either (error.show) (findMetadata dir) . P.parse namedMetadata path <$> readFile path
157153 findMetadata dir =
158− concatMap snd . filter (flip matches (fromFilePath fp) . fromGlob . combine dir . fst)
154+ concatMap snd . filter (flip matches fp . fromGlob . combine dir . fst)
159155
160156namedMetadata :: Parser [(String, [(String, String)])]
161157namedMetadata = P.many namedMetadataBlock
src/Hakyll/Core/Rules/Default.hsnew file+23
@@ -0,0 +1,23 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+module Hakyll.Core.Rules.Default
3+ ( internalRules
4+ , addMetadataDependencies
5+ )
6+where
7+import Hakyll.Core.Rules
8+import Hakyll.Core.Compiler
9+import Hakyll.Core.Compiler.Internal (compilerTellDependencies)
10+import Hakyll.Core.Metadata (getMatches, metadataFiles)
11+import Hakyll.Core.Identifier.Pattern(fromList)
12+
13+internalRules :: Rules ()
14+internalRules = do
15+ match "metadata" $ compile $ makeItem ()
16+ match "**/metadata" $ compile $ makeItem ()
17+
18+--------------------------------------------------------------------------------
19+addMetadataDependencies :: Compiler ()
20+addMetadataDependencies =
21+ compilerTellDependencies . map IdentifierDependency =<< getMatches . fromList =<< fmap metadataFiles getUnderlying
22+
23+
src/Hakyll/Core/Runtime.hs+3−2
@@ -35,6 +35,7 @@ import qualified Hakyll.Core.Logger as Logger
3535import Hakyll.Core.Provider
3636import Hakyll.Core.Routes
3737import Hakyll.Core.Rules.Internal
38+import Hakyll.Core.Rules.Default
3839import Hakyll.Core.Store (Store)
3940import qualified Hakyll.Core.Store as Store
4041import Hakyll.Core.Util.File
@@ -53,7 +54,7 @@ run config verbosity rules = do
5354 provider <- newProvider store (shouldIgnoreFile config) $
5455 providerDirectory config
5556 Logger.message logger "Running rules..."
56− ruleSet <- runRules rules provider
57+ ruleSet <- runRules (internalRules >> rules) provider
5758
5859 -- Get old facts
5960 mOldFacts <- Store.get store factsKey
@@ -186,7 +187,7 @@ chase trail id'
186187 config <- runtimeConfiguration <$> ask
187188 Logger.debug logger $ "Processing " ++ show id'
188189
189− let compiler = todo M.! id'
190+ let compiler = addMetadataDependencies >> todo M.! id'
190191 read' = CompilerRead
191192 { compilerConfig = config
192193 , compilerUnderlying = id'