on master help sign in
Prototype Run module
ec85de4Jasper Van der Jeugt
src/Hakyll/Core/Run.hsnew file+68
@@ -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'
src/Hakyll/Core/Target.hs+14
@@ -6,6 +6,20 @@ module Hakyll.Core.Target
6 , TargetM
6 , TargetM
7 , Target
7 , Target
8 , runTarget
8 , runTarget
9+ , getResourceString
9 ) where
10 ) where
10
11
12+import Control.Applicative ((<$>))
13+import Control.Monad.Reader (ask)
14+import Control.Monad.Trans (liftIO)
15+
11import Hakyll.Core.Target.Internal
16import Hakyll.Core.Target.Internal
17+import Hakyll.Core.ResourceProvider
18+
19+-- | Get the resource content as a string
20+--
21+getResourceString :: TargetM a String
22+getResourceString = TargetM $ do
23+ provider <- targetResourceProvider <$> ask
24+ identifier <- targetIdentifier <$> ask
25+ liftIO $ resourceString provider identifier
src/Hakyll/Core/Target/Internal.hs+12−4
@@ -9,10 +9,12 @@ module Hakyll.Core.Target.Internal
9 , runTarget
9 , runTarget
10 ) where
10 ) where
11
11
12+import Control.Applicative (Applicative)
12import Control.Monad.Trans (MonadIO)
13import Control.Monad.Trans (MonadIO)
13import Control.Monad.Reader (ReaderT, runReaderT)
14import Control.Monad.Reader (ReaderT, runReaderT)
14
15
15import Hakyll.Core.Identifier
16import Hakyll.Core.Identifier
17+import Hakyll.Core.ResourceProvider
16
18
17-- | A lookup with which we can get dependencies
19-- | A lookup with which we can get dependencies
18--
20--
@@ -21,15 +23,16 @@ type DependencyLookup a = Identifier -> a
21-- | Environment for the target monad
23-- | Environment for the target monad
22--
24--
23data TargetEnvironment a = TargetEnvironment
25data TargetEnvironment a = TargetEnvironment
24− { targetIdentifier :: Identifier
26+ { targetIdentifier :: Identifier -- ^ Identifier
25 , targetDependencyLookup :: DependencyLookup a -- ^ Dependency lookup
27 , targetDependencyLookup :: DependencyLookup a -- ^ Dependency lookup
28+ , targetResourceProvider :: ResourceProvider -- ^ To get resources
26 }
29 }
27
30
28-- | Monad for targets. In this monad, the user can compose targets and describe
31-- | Monad for targets. In this monad, the user can compose targets and describe
29-- how they should be created.
32-- how they should be created.
30--
33--
31newtype TargetM a b = TargetM {unTargetM :: ReaderT (TargetEnvironment a) IO b}
34newtype TargetM a b = TargetM {unTargetM :: ReaderT (TargetEnvironment a) IO b}
32− deriving (Monad, Functor, MonadIO)
35+ deriving (Monad, Functor, Applicative, MonadIO)
33
36
34-- | Simplification of the 'TargetM' type for concrete cases: the type of the
37-- | Simplification of the 'TargetM' type for concrete cases: the type of the
35-- returned item should equal the type of the dependencies.
38-- returned item should equal the type of the dependencies.
@@ -38,10 +41,15 @@ type Target a = TargetM a a
38
41
39-- | Run a target, yielding an actual result.
42-- | Run a target, yielding an actual result.
40--
43--
44+runTarget :: Target a
45+ -> Identifier
41−runTarget :: Target a -> Identifier -> DependencyLookup a -> IO a
46+ -> DependencyLookup a
47+ -> ResourceProvider
48+ -> IO a
42−runTarget target id' lookup' = runReaderT (unTargetM target) env
49+runTarget target id' lookup' provider = runReaderT (unTargetM target) env
43 where
50 where
44 env = TargetEnvironment
51 env = TargetEnvironment
45 { targetIdentifier = id'
52 { targetIdentifier = id'
46 , targetDependencyLookup = lookup'
53 , targetDependencyLookup = lookup'
54+ , targetResourceProvider = provider
47 }
55 }