summaryrefslogtreecommitdiff
path: root/src/Hakyll
diff options
context:
space:
mode:
authorAlexey Kreshchuk <akrsch@gmail.com>2013-10-16 01:39:04 +0400
committerAlexey Kreshchuk <akrsch@gmail.com>2013-10-16 01:39:04 +0400
commit712ffa39b5857fdc5cdae1db38a177267a430b11 (patch)
treeb4b5f7c46f769dc176932894bbafe0878da99e3a /src/Hakyll
parenta6ae4eb99dd5f9957adc3b5fe4011e69b9681e4c (diff)
downloadhakyll-712ffa39b5857fdc5cdae1db38a177267a430b11.tar.gz
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.
Diffstat (limited to 'src/Hakyll')
-rw-r--r--src/Hakyll/Core/Metadata.hs10
-rw-r--r--src/Hakyll/Core/Provider/Metadata.hs20
-rw-r--r--src/Hakyll/Core/Rules/Default.hs23
-rw-r--r--src/Hakyll/Core/Runtime.hs5
4 files changed, 44 insertions, 14 deletions
diff --git a/src/Hakyll/Core/Metadata.hs b/src/Hakyll/Core/Metadata.hs
index 7902b94..a330636 100644
--- a/src/Hakyll/Core/Metadata.hs
+++ b/src/Hakyll/Core/Metadata.hs
@@ -5,6 +5,7 @@ module Hakyll.Core.Metadata
, getMetadataField
, getMetadataField'
, makePatternDependency
+ , metadataFiles
) where
@@ -12,6 +13,7 @@ module Hakyll.Core.Metadata
import Control.Monad (forM)
import Data.Map (Map)
import qualified Data.Map as M
+import System.FilePath.Posix ((</>), takeDirectory)
--------------------------------------------------------------------------------
@@ -61,3 +63,11 @@ makePatternDependency :: MonadMetadata m => Pattern -> m Dependency
makePatternDependency pattern = do
matches' <- getMatches pattern
return $ PatternDependency pattern matches'
+
+--------------------------------------------------------------------------------
+-- | Returns a list of all directory-wise metadata files, subdir first, global last
+metadataFiles :: Identifier -> [Identifier]
+metadataFiles = go . takeDirectory . toFilePath where
+ go "." = [fromFilePath "metadata"]
+ go dir = fromFilePath (dir </> "metadata") : go (takeDirectory dir)
+
diff --git a/src/Hakyll/Core/Provider/Metadata.hs b/src/Hakyll/Core/Provider/Metadata.hs
index 8f39f22..4331861 100644
--- a/src/Hakyll/Core/Provider/Metadata.hs
+++ b/src/Hakyll/Core/Provider/Metadata.hs
@@ -44,7 +44,7 @@ loadMetadata p identifier = do
Nothing -> return M.empty
Just mi' -> loadMetadataFile $ resourceFilePath p mi'
- gmd <- loadGlobalMetadata p $ toFilePath identifier
+ gmd <- loadGlobalMetadata p identifier
return (M.unions [md, emd, gmd], body)
where
@@ -141,21 +141,17 @@ page = do
--------------------------------------------------------------------------------
-- | Load directory-wise metadata
-loadGlobalMetadata :: Provider -> FilePath -> IO (M.Map String String)
-loadGlobalMetadata p fp = liftM M.fromList $ loadgm $ takeDirectory fp where
- loadgm :: FilePath -> IO [(String, String)]
- loadgm dir | dir == "." = return []
- | otherwise = do
- let mfp = fromFilePath $ combine dir "metadata"
- md <- if resourceExists p mfp then loadOne mfp dir else return []
- others <- loadgm (takeDirectory dir)
- return $ others ++ md
- loadOne mfp dir =
+loadGlobalMetadata :: Provider -> Identifier -> IO Metadata
+loadGlobalMetadata p fp = liftM M.fromList $ loadgm fp where
+ loadgm :: Identifier -> IO [(String, String)]
+ loadgm = liftM concat . mapM loadOne . reverse . filter (resourceExists p) . metadataFiles
+ loadOne mfp =
let path = resourceFilePath p mfp
+ dir = takeDirectory $ toFilePath mfp
-- TODO: It might be better to print warning and continue
in either (error.show) (findMetadata dir) . P.parse namedMetadata path <$> readFile path
findMetadata dir =
- concatMap snd . filter (flip matches (fromFilePath fp) . fromGlob . combine dir . fst)
+ concatMap snd . filter (flip matches fp . fromGlob . combine dir . fst)
namedMetadata :: Parser [(String, [(String, String)])]
namedMetadata = P.many namedMetadataBlock
diff --git a/src/Hakyll/Core/Rules/Default.hs b/src/Hakyll/Core/Rules/Default.hs
new file mode 100644
index 0000000..ccca1bd
--- /dev/null
+++ b/src/Hakyll/Core/Rules/Default.hs
@@ -0,0 +1,23 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Hakyll.Core.Rules.Default
+ ( internalRules
+ , addMetadataDependencies
+ )
+where
+import Hakyll.Core.Rules
+import Hakyll.Core.Compiler
+import Hakyll.Core.Compiler.Internal (compilerTellDependencies)
+import Hakyll.Core.Metadata (getMatches, metadataFiles)
+import Hakyll.Core.Identifier.Pattern(fromList)
+
+internalRules :: Rules ()
+internalRules = do
+ match "metadata" $ compile $ makeItem ()
+ match "**/metadata" $ compile $ makeItem ()
+
+--------------------------------------------------------------------------------
+addMetadataDependencies :: Compiler ()
+addMetadataDependencies =
+ compilerTellDependencies . map IdentifierDependency =<< getMatches . fromList =<< fmap metadataFiles getUnderlying
+
+
diff --git a/src/Hakyll/Core/Runtime.hs b/src/Hakyll/Core/Runtime.hs
index 824d11b..4ef30df 100644
--- a/src/Hakyll/Core/Runtime.hs
+++ b/src/Hakyll/Core/Runtime.hs
@@ -35,6 +35,7 @@ import qualified Hakyll.Core.Logger as Logger
import Hakyll.Core.Provider
import Hakyll.Core.Routes
import Hakyll.Core.Rules.Internal
+import Hakyll.Core.Rules.Default
import Hakyll.Core.Store (Store)
import qualified Hakyll.Core.Store as Store
import Hakyll.Core.Util.File
@@ -53,7 +54,7 @@ run config verbosity rules = do
provider <- newProvider store (shouldIgnoreFile config) $
providerDirectory config
Logger.message logger "Running rules..."
- ruleSet <- runRules rules provider
+ ruleSet <- runRules (internalRules >> rules) provider
-- Get old facts
mOldFacts <- Store.get store factsKey
@@ -186,7 +187,7 @@ chase trail id'
config <- runtimeConfiguration <$> ask
Logger.debug logger $ "Processing " ++ show id'
- let compiler = todo M.! id'
+ let compiler = addMetadataDependencies >> todo M.! id'
read' = CompilerRead
{ compilerConfig = config
, compilerUnderlying = id'