@@ -3,13 +3,16 @@
3module Hakyll.Core.Run where
3module Hakyll.Core.Run where
5import Control.Arrow ((&&&))
5import Control.Arrow ((&&&))
6−import Control.Monad (foldM, forM_, forM)
6+import Control.Monad (foldM, forM_, forM, filterM)
7import qualified Data.Map as M
8import qualified Data.Map as M
8import Data.Monoid (mempty)
9import Data.Monoid (mempty)
9import Data.Typeable (Typeable)
10import Data.Typeable (Typeable)
10import Data.Binary (Binary)
11import Data.Binary (Binary)
11import System.FilePath ((</>))
12import System.FilePath ((</>))
12import Control.Applicative ((<$>))
13import Control.Applicative ((<$>))
15+import qualified Data.Set as S
14import Hakyll.Core.Route
17import Hakyll.Core.Route
15import Hakyll.Core.Identifier
18import Hakyll.Core.Identifier
@@ -22,6 +25,7 @@ import Hakyll.Core.Rules
22import Hakyll.Core.DirectedGraph
25import Hakyll.Core.DirectedGraph
23import Hakyll.Core.DirectedGraph.Dot
26import Hakyll.Core.DirectedGraph.Dot
24import Hakyll.Core.DirectedGraph.DependencySolver
27import Hakyll.Core.DirectedGraph.DependencySolver
28+import Hakyll.Core.DirectedGraph.ObsoleteFilter
25import Hakyll.Core.Writable
29import Hakyll.Core.Writable
26import Hakyll.Core.Store
30import Hakyll.Core.Store
27import Hakyll.Core.CompiledItem
31import Hakyll.Core.CompiledItem
@@ -48,9 +52,23 @@ hakyllWith rules provider store = do
48 -- Create a compiler map
52 -- Create a compiler map
49 compilerMap = M.fromList compilers
53 compilerMap = M.fromList compilers
51− -- Create and solve the graph, creating a compiler order
55+ -- Create the graph
52 graph = fromList dependencies
56 graph = fromList dependencies
58+ putStrLn "Writing dependency graph to dependencies.dot..."
59+ writeDot "dependencies.dot" show graph
61+ -- Check which items are up-to-date
62+ modified' <- modified provider store $ map fst compilers
64+ let -- Try to reduce the graph
65+ reducedGraph = filterObsolete modified' graph
67+ putStrLn "Writing reduced graph to reduced.dot..."
68+ writeDot "reduced.dot" show reducedGraph
70+ let -- Solve the graph
53− ordered = solveDependencies graph
71+ ordered = solveDependencies reducedGraph
55 -- Join the order with the compilers again
73 -- Join the order with the compilers again
56 orderedCompilers = map (id &&& (compilerMap M.!)) ordered
74 orderedCompilers = map (id &&& (compilerMap M.!)) ordered
@@ -58,30 +76,23 @@ hakyllWith rules provider store = do
58 -- Fetch the routes
76 -- Fetch the routes
59 route' = rulesRoute ruleSet
77 route' = rulesRoute ruleSet
61− putStrLn "Writing dependency graph to dependencies.dot..."
79+ putStrLn $ show reducedGraph
62− writeDot "dependencies.dot" show graph
80+ putStrLn $ show ordered
64− -- Check which items are up-to-date: modified will be a Map Identifier Bool
65− modifiedMap <- fmap M.fromList $ forM orderedCompilers $ \(id', _) -> do
66− modified <- if resourceExists provider id'
67− then resourceModified provider id' store
69− return (id', modified)
71 -- Generate all the targets in order
82 -- Generate all the targets in order
72− _ <- foldM (addTarget route' modifiedMap) M.empty orderedCompilers
83+ _ <- foldM (addTarget route' modified') M.empty orderedCompilers
74 putStrLn "DONE."
85 putStrLn "DONE."
76− addTarget route' modifiedMap map' (id', comp) = do
87+ addTarget route' modified' map' (id', comp) = do
77 let url = runRoute route' id'
88 let url = runRoute route' id'
79 -- Check if the resource was modified
90 -- Check if the resource was modified
80− let modified = modifiedMap M.! id'
91+ let isModified = id' `S.member` modified'
82 -- Run the compiler
93 -- Run the compiler
83 compiled <- runCompilerJob comp id' provider (dependencyLookup map')
94 compiled <- runCompilerJob comp id' provider (dependencyLookup map')
84− url store modified
95+ url store isModified
85 putStrLn $ "Generated target: " ++ show id'
96 putStrLn $ "Generated target: " ++ show id'
87 case url of
98 case url of
@@ -92,9 +103,18 @@ hakyllWith rules provider store = do
92 makeDirectories path
103 makeDirectories path
93 write path compiled
104 write path compiled
106+ -- Store it in the cache
107+ storeResult store id' compiled
95 putStrLn ""
109 putStrLn ""
96 return $ M.insert id' compiled map'
110 return $ M.insert id' compiled map'
98− dependencyLookup map' id' = case M.lookup id' map' of
112+ dependencyLookup map' id' = M.lookup id' map'
99− Nothing -> error $ "dependencyLookup: " ++ show id' ++ " not found"
113+
100− Just d -> d
114+modified :: ResourceProvider -- ^ Resource provider
116+ -> [Identifier] -- ^ Identifiers to check
117+ -> IO (Set Identifier) -- ^ Modified resources
118+modified provider store ids = fmap S.fromList $ flip filterM ids $ \id' ->
119+ if resourceExists provider id' then resourceModified provider id' store