@@ -0,0 +1,68 @@
1+-- | This is the module which binds it all together
2+--
3+module Hakyll.Core.Run where
4+
5+import Control.Arrow ((&&&))
6+import Control.Monad (msum, foldM, forM, forM_)
7+import qualified Data.Map as M
8+
9+import Hakyll.Core.Route
10+import Hakyll.Core.Compiler
11+import Hakyll.Core.ResourceProvider
12+import Hakyll.Core.ResourceProvider.FileResourceProvider
13+import Hakyll.Core.Rules
14+import Hakyll.Core.Target
15+import Hakyll.Core.Identifier
16+import Hakyll.Core.DirectedGraph
17+import Hakyll.Core.DirectedGraph.DependencySolver
18+import Hakyll.Core.Writable
19+
20+hakyll :: Writable a => Rules a -> IO ()
21+hakyll rules = do
22+ provider <- fileResourceProvider
23+ hakyllWith rules provider
24+
25+hakyllWith :: Writable a => Rules a -> ResourceProvider -> IO ()
26+hakyllWith rules provider = do
27+ let -- Get the rule set
28+ ruleSet = runRules rules provider
29+
30+ -- Get all identifiers and compilers
31+ compilers = rulesCompilers ruleSet
32+
33+ -- Get all targets
34+ targets = flip map compilers $ \(id', compiler) ->
35+ let (targ, deps) = runCompiler compiler id'
36+ in (id', targ, deps)
37+
38+ -- Map mapping every identifier to it's target
39+ targetMap = M.fromList $ map (\(i, t, _) -> (i, t)) targets
40+
41+ -- Create a dependency graph
42+ graph = fromList $ map (\(i, _, d) -> (i, d)) targets
43+
44+ -- Solve the graph, creating a target order
45+ ordered = solveDependencies graph
46+
47+ -- Join the order with the targets again
48+ orderedTargets = map (id &&& (targetMap M.!)) ordered
49+
50+ -- Generate all the targets in order
51+ map' <- foldM addTarget M.empty orderedTargets
52+
53+ let -- Fetch the routes
54+ route' = rulesRoute ruleSet
55+
56+ forM_ (M.toList map') $ \(id', result) ->
57+ case runRoute route' id' of
58+ Nothing -> return ()
59+ Just r -> do
60+ putStrLn $ "Routing " ++ show id' ++ " to " ++ r
61+ write r result
62+
63+ putStrLn "DONE."
64+ where
65+ addTarget map' (id', targ) = do
66+ result <- runTarget targ id' (map' M.!) provider
67+ putStrLn $ "Generated target: " ++ show id'
68+ return $ M.insert id' result map'