1+ {-# LANGUAGE QuasiQuotes #-}
12{-# LANGUAGE TemplateHaskellQuotes #-}
23
34-- | Copyright : (c) Crown Copyright GCHQ
@@ -17,41 +18,65 @@ import Bootstrap.Data.Bootstrappable
1718 )
1819import Bootstrap.Data.ProjectType
1920 ( HaskellOptions (HaskellOptions ),
20- HaskellProjectType (HaskellProjectTypeBasic , HaskellProjectTypeReplOnly ),
21+ HaskellProjectType (HaskellProjectTypeBasic , HaskellProjectTypeReplOnly , HaskellProjectTypeServer ),
2122 ProjectType (Haskell ),
2223 )
2324import Control.Lens ((?~) )
25+ import Language.Haskell.TH (appE , conT , varE )
2426import Language.Haskell.TH.Syntax
2527 ( Body (NormalB ),
2628 Clause (Clause ),
2729 Dec (FunD , SigD ),
28- Exp (VarE ),
30+ Exp (DoE , VarE ),
2931 ModName (ModName ),
30- Type ( AppT , ConT ),
32+ Stmt ( NoBindS ),
3133 mkName ,
3234 )
3335
34- data MainHs = MainHs
36+ data MainHs
37+ = -- | Simply calls Lib.lib
38+ MainHsLib
39+ | -- | Uses Server.app (a WAI Application) to run a warp server on port 8080
40+ MainHsWarp
3541
3642instance Bootstrappable MainHs where
3743 bootstrapName = const " app/Main.hs"
3844 bootstrapReason = const " The entrypoint of your haskell executable"
39- bootstrapContent MainHs = do
40- let main = mkName " main"
41- io = mkName " IO"
45+ bootstrapContent mainHs = do
46+ let app = mkName " app"
4247 lib = mkName " lib"
43- unitType <- [t |()|]
48+ main = mkName " main"
49+ run = mkName " run"
50+ ioUnit <- [t |$(conT $ mkName "IO") ()|]
51+ logServing <- [| putTextLn " Serving on 8080..." | ]
52+ runServer <- varE run `appE` [| 8080 | ] `appE` varE app
4453 pure . pure . bootstrapContentHaskell $
4554 haskellModule (ModName " Main" ) (one " main" )
4655 & haskellModuleImports
47- ?~ one (HaskellImport (ModName " Lib" ) [lib])
56+ ?~ ( case mainHs of
57+ MainHsLib -> one (HaskellImport (ModName " Lib" ) [" lib" ])
58+ MainHsWarp ->
59+ HaskellImport (ModName " Network.Wai.Handler.Warp" ) [" run" ]
60+ :| [HaskellImport (ModName " Server" ) [" app" ]]
61+ )
4862 & haskellModuleDecs
49- ?~ SigD main (AppT (ConT io) unitType)
50- :| [FunD main [Clause [] (NormalB $ VarE lib) [] ]]
63+ ?~ SigD main ioUnit
64+ :| [ FunD
65+ main
66+ [ Clause
67+ []
68+ ( NormalB $ case mainHs of
69+ MainHsLib -> VarE lib
70+ MainHsWarp -> DoE Nothing [NoBindS logServing, NoBindS runServer]
71+ )
72+ []
73+ ]
74+ ]
5175
5276mainHsFor :: ProjectType -> Maybe MainHs
5377mainHsFor = \ case
5478 Haskell (HaskellOptions _ haskellProjectType) -> case haskellProjectType of
5579 HaskellProjectTypeReplOnly -> Nothing
56- HaskellProjectTypeBasic _ -> Just MainHs
80+ HaskellProjectTypeBasic _ -> Just MainHsLib
81+ HaskellProjectTypeServer _ -> Just MainHsWarp
5782 _ -> Nothing
0 commit comments