@@ -11,13 +11,11 @@ import Control.Monad.Trans (liftIO)
11import Control.Applicative (Applicative, (<$>))
11import Control.Applicative (Applicative, (<$>))
12import Control.Monad.Reader (ReaderT, runReaderT, ask)
12import Control.Monad.Reader (ReaderT, runReaderT, ask)
13import Control.Monad.State.Strict (StateT, runStateT, get, put)
13import Control.Monad.State.Strict (StateT, runStateT, get, put)
14−import Control.Arrow ((&&&))
15import Data.Map (Map)
14import Data.Map (Map)
16import qualified Data.Map as M
15import qualified Data.Map as M
17import Data.Monoid (mempty, mappend)
16import Data.Monoid (mempty, mappend)
18import Data.Maybe (fromMaybe)
17import Data.Maybe (fromMaybe)
19import System.FilePath ((</>))
18import System.FilePath ((</>))
21import qualified Data.Set as S
19import qualified Data.Set as S
23import Hakyll.Core.Routes
21import Hakyll.Core.Routes
@@ -31,7 +29,6 @@ import Hakyll.Core.Resource.Provider.File
31import Hakyll.Core.Rules.Internal
29import Hakyll.Core.Rules.Internal
32import Hakyll.Core.DirectedGraph
30import Hakyll.Core.DirectedGraph
33import Hakyll.Core.DirectedGraph.Dot
31import Hakyll.Core.DirectedGraph.Dot
34−import Hakyll.Core.DirectedGraph.DependencySolver
35import Hakyll.Core.DependencyAnalyzer
32import Hakyll.Core.DependencyAnalyzer
36import Hakyll.Core.Writable
33import Hakyll.Core.Writable
37import Hakyll.Core.Store
34import Hakyll.Core.Store
@@ -65,14 +62,12 @@ run configuration rules = do
65 , hakyllRoutes = rulesRoutes ruleSet
62 , hakyllRoutes = rulesRoutes ruleSet
66 , hakyllResourceProvider = provider
63 , hakyllResourceProvider = provider
67 , hakyllStore = store
64 , hakyllStore = store
68− , hakyllOldGraph = oldGraph
71 -- Run the program and fetch the resulting state
67 -- Run the program and fetch the resulting state
72 ((), state') <- runStateT stateT $ RuntimeState
68 ((), state') <- runStateT stateT $ RuntimeState
73 { hakyllAnalyzer = makeDependencyAnalyzer mempty (const False) oldGraph
69 { hakyllAnalyzer = makeDependencyAnalyzer mempty (const False) oldGraph
74 , hakyllCompilers = M.empty
70 , hakyllCompilers = M.empty
75− , hakyllModified = S.empty
78 -- We want to save the final dependency graph for the next run
73 -- We want to save the final dependency graph for the next run
@@ -89,13 +84,11 @@ data RuntimeEnvironment = RuntimeEnvironment
89 , hakyllRoutes :: Routes
84 , hakyllRoutes :: Routes
90 , hakyllResourceProvider :: ResourceProvider
85 , hakyllResourceProvider :: ResourceProvider
91 , hakyllStore :: Store
86 , hakyllStore :: Store
92− , hakyllOldGraph :: DirectedGraph Identifier
95data RuntimeState = RuntimeState
89data RuntimeState = RuntimeState
96 { hakyllAnalyzer :: DependencyAnalyzer Identifier
90 { hakyllAnalyzer :: DependencyAnalyzer Identifier
97 , hakyllCompilers :: Map Identifier (Compiler () CompileRule)
91 , hakyllCompilers :: Map Identifier (Compiler () CompileRule)
98− , hakyllModified :: Set Identifier
101newtype Runtime a = Runtime
94newtype Runtime a = Runtime
@@ -104,12 +97,14 @@ newtype Runtime a = Runtime
105-- | Return a set of modified identifiers
98-- | Return a set of modified identifiers
107modified :: ResourceProvider -- ^ Resource provider
101modified :: ResourceProvider -- ^ Resource provider
108 -> Store -- ^ Store
102 -> Store -- ^ Store
109 -> [Identifier] -- ^ Identifiers to check
103 -> [Identifier] -- ^ Identifiers to check
110 -> IO (Set Identifier) -- ^ Modified resources
104 -> IO (Set Identifier) -- ^ Modified resources
111modified provider store ids = fmap S.fromList $ flip filterM ids $ \id' ->
105modified provider store ids = fmap S.fromList $ flip filterM ids $ \id' ->
112 resourceModified provider (Resource id') store
106 resourceModified provider (Resource id') store
114-- | Add a number of compilers and continue using these compilers
109-- | Add a number of compilers and continue using these compilers
@@ -126,7 +121,6 @@ addNewCompilers newCompilers = Runtime $ do
126 -- Old state information
121 -- Old state information
127 oldCompilers <- hakyllCompilers <$> get
122 oldCompilers <- hakyllCompilers <$> get
128 oldAnalyzer <- hakyllAnalyzer <$> get
123 oldAnalyzer <- hakyllAnalyzer <$> get
129− oldModified <- hakyllModified <$> get
131 let -- Create a new partial dependency graph
125 let -- Create a new partial dependency graph
132 dependencies = flip map newCompilers $ \(id', compiler) ->
126 dependencies = flip map newCompilers $ \(id', compiler) ->
@@ -137,18 +131,30 @@ addNewCompilers newCompilers = Runtime $ do
137 newGraph = fromList dependencies
131 newGraph = fromList dependencies
139 -- Check which items have been modified
133 -- Check which items have been modified
134+ modified <- fmap S.fromList $ flip filterM (map fst newCompilers) $
135+ liftIO . resourceModified provider store . Resource
140− newModified <- liftIO $ modified provider store $ map fst newCompilers
136+ -- newModified <- liftIO $ modified provider store $ map fst newCompilers
142 -- Create a new analyzer and append it to the currect one
138 -- Create a new analyzer and append it to the currect one
144− makeDependencyAnalyzer newGraph (`S.member` newModified) mempty
139+ let newAnalyzer = makeDependencyAnalyzer newGraph (`S.member` modified) $
140+ analyzerPreviousGraph oldAnalyzer
145 analyzer = mappend oldAnalyzer newAnalyzer
141 analyzer = mappend oldAnalyzer newAnalyzer
144+ liftIO $ putStrLn $ "Remains: " ++ show (analyzerRemains newAnalyzer)
145+ liftIO $ putStrLn $ "Done: " ++ show (analyzerDone newAnalyzer)
146+ liftIO $ writeFile "old-prev.dot" $ toDot show (analyzerPreviousGraph oldAnalyzer)
147+ liftIO $ writeFile "old.dot" $ toDot show (analyzerGraph oldAnalyzer)
148+ liftIO $ writeFile "old-prev.dot" $ toDot show (analyzerPreviousGraph oldAnalyzer)
149+ liftIO $ writeFile "new.dot" $ toDot show (analyzerGraph newAnalyzer)
150+ liftIO $ writeFile "new-prev.dot" $ toDot show (analyzerPreviousGraph newAnalyzer)
151+ liftIO $ writeFile "result.dot" $ toDot show (analyzerGraph analyzer)
152+ liftIO $ writeFile "result-prev.dot" $ toDot show (analyzerPreviousGraph analyzer)
147 -- Update the state
154 -- Update the state
148 put $ RuntimeState
155 put $ RuntimeState
149 { hakyllAnalyzer = analyzer
156 { hakyllAnalyzer = analyzer
150 , hakyllCompilers = M.union oldCompilers (M.fromList newCompilers)
157 , hakyllCompilers = M.union oldCompilers (M.fromList newCompilers)
151− , hakyllModified = S.union oldModified newModified
154 -- Continue
160 -- Continue
@@ -162,7 +168,7 @@ stepAnalyzer = Runtime $ do
162 put $ state { hakyllAnalyzer = analyzer' }
168 put $ state { hakyllAnalyzer = analyzer' }
164 case signal of Done -> return ()
170 case signal of Done -> return ()
165− Cycle c -> return ()
171+ Cycle _ -> return ()
166 Build id' -> unRuntime $ build id'
172 Build id' -> unRuntime $ build id'
168build :: Identifier -> Runtime ()
174build :: Identifier -> Runtime ()
@@ -171,16 +177,15 @@ build id' = Runtime $ do
171 routes <- hakyllRoutes <$> ask
177 routes <- hakyllRoutes <$> ask
172 provider <- hakyllResourceProvider <$> ask
178 provider <- hakyllResourceProvider <$> ask
173 store <- hakyllStore <$> ask
179 store <- hakyllStore <$> ask
174− modified' <- hakyllModified <$> get
175 compilers <- hakyllCompilers <$> get
180 compilers <- hakyllCompilers <$> get
177 section logger $ "Compiling " ++ show id'
182 section logger $ "Compiling " ++ show id'
179− let -- Fetch the right compiler from the map
184+ -- Fetch the right compiler from the map
180− compiler = compilers M.! id'
185+ let compiler = compilers M.! id'
182− -- Check if the resource was modified
187+ -- Check if the resource was modified
183− isModified = id' `S.member` modified'
188+ isModified <- liftIO $ resourceModified provider store (Resource id')
185 -- Run the compiler
190 -- Run the compiler
186 result <- timed logger "Total compile time" $ liftIO $
191 result <- timed logger "Total compile time" $ liftIO $