-- | This is the module which binds it all together -- module Hakyll.Core.Run where import Control.Arrow ((&&&)) import Control.Monad (foldM, forM_) import qualified Data.Map as M import Data.Monoid (mempty) import Data.Typeable (Typeable) import Data.Binary (Binary) import System.FilePath (()) import Hakyll.Core.Route import Hakyll.Core.Identifier import Hakyll.Core.Util.File import Hakyll.Core.Compiler import Hakyll.Core.Compiler.Internal import Hakyll.Core.ResourceProvider import Hakyll.Core.ResourceProvider.FileResourceProvider import Hakyll.Core.Rules import Hakyll.Core.DirectedGraph import Hakyll.Core.DirectedGraph.Dot import Hakyll.Core.DirectedGraph.DependencySolver import Hakyll.Core.Writable import Hakyll.Core.Store import Hakyll.Core.CompiledItem hakyll :: Rules -> IO () hakyll rules = do store <- makeStore "_store" provider <- fileResourceProvider hakyllWith rules provider store hakyllWith :: Rules -> ResourceProvider -> Store -> IO () hakyllWith rules provider store = do let -- Get the rule set ruleSet = runRules rules provider -- Get all identifiers and compilers compilers = rulesCompilers ruleSet -- Get all dependencies dependencies = flip map compilers $ \(id', compiler) -> let deps = runCompilerDependencies compiler provider in (id', deps) -- Create a compiler map compilerMap = M.fromList compilers -- Create and solve the graph, creating a compiler order graph = fromList dependencies ordered = solveDependencies graph -- Join the order with the compilers again orderedCompilers = map (id &&& (compilerMap M.!)) ordered -- Fetch the routes route' = rulesRoute ruleSet putStrLn "Writing dependency graph to dependencies.dot..." writeDot "dependencies.dot" show graph -- Generate all the targets in order _ <- foldM (addTarget route') M.empty orderedCompilers putStrLn "DONE." where addTarget route' map' (id', comp) = do let url = runRoute route' id' compiled <- runCompilerJob comp id' provider (dependencyLookup map') url store putStrLn $ "Generated target: " ++ show id' case url of Nothing -> return () Just r -> do putStrLn $ "Routing " ++ show id' ++ " to " ++ r let path = "_site" r makeDirectories path write path compiled return $ M.insert id' compiled map' dependencyLookup map' id' = case M.lookup id' map' of Nothing -> error $ "dependencyLookup: " ++ show id' ++ " not found" Just d -> d