fix/improve scaffolding
This commit is contained in:
parent
a0a7291616
commit
7fd7ba59ca
@ -46,10 +46,10 @@ with~sitearg~ conf f = do
|
|||||||
|
|
||||||
with~sitearg~LoadConfig :: Settings.AppEnvironment -> (Application -> IO a) -> IO a
|
with~sitearg~LoadConfig :: Settings.AppEnvironment -> (Application -> IO a) -> IO a
|
||||||
with~sitearg~LoadConfig env f = do
|
with~sitearg~LoadConfig env f = do
|
||||||
conf <- Settings.loadConfig Settings.Development
|
conf <- Settings.loadConfig env
|
||||||
withFoobar conf f
|
withFoobar conf f
|
||||||
|
|
||||||
|
-- for yesod devel
|
||||||
withDevelApp :: Dynamic
|
withDevelApp :: Dynamic
|
||||||
withDevelApp = do
|
withDevelApp = do
|
||||||
toDyn ((with~sitearg~LoadConfig Settings.Development):: (Application -> IO ()) -> IO ())
|
toDyn ((with~sitearg~LoadConfig Settings.Development):: (Application -> IO ()) -> IO ())
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
module Handler.Root where
|
module Handler.Root where
|
||||||
|
|
||||||
import ~sitearg~
|
import ~sitearg~
|
||||||
|
import Data.Text
|
||||||
|
|
||||||
-- This is a handler function for the GET request method on the RootR
|
-- This is a handler function for the GET request method on the RootR
|
||||||
-- resource pattern. All of your resource patterns are defined in
|
-- resource pattern. All of your resource patterns are defined in
|
||||||
@ -17,4 +18,3 @@ getRootR = do
|
|||||||
h2id <- lift newIdent
|
h2id <- lift newIdent
|
||||||
setTitle "~project~ homepage"
|
setTitle "~project~ homepage"
|
||||||
addWidget $(widgetFile "homepage")
|
addWidget $(widgetFile "homepage")
|
||||||
|
|
||||||
|
|||||||
@ -31,7 +31,8 @@ import Language.Haskell.TH.Syntax
|
|||||||
import Yesod (liftIO, MonadControlIO, addWidget, addCassius, addJulius, addLucius)
|
import Yesod (liftIO, MonadControlIO, addWidget, addCassius, addJulius, addLucius)
|
||||||
import Data.Monoid (mempty, mappend)
|
import Data.Monoid (mempty, mappend)
|
||||||
import System.Directory (doesFileExist)
|
import System.Directory (doesFileExist)
|
||||||
import Data.Text (Text)
|
import Prelude hiding (concat)
|
||||||
|
import Data.Text (Text, snoc, append, pack, concat)
|
||||||
import Data.Object
|
import Data.Object
|
||||||
import qualified Data.Object.Yaml as YAML
|
import qualified Data.Object.Yaml as YAML
|
||||||
import Control.Monad (join)
|
import Control.Monad (join)
|
||||||
|
|||||||
@ -5,4 +5,3 @@
|
|||||||
/robots.txt RobotsR GET
|
/robots.txt RobotsR GET
|
||||||
|
|
||||||
/ RootR GET
|
/ RootR GET
|
||||||
|
|
||||||
|
|||||||
@ -34,13 +34,19 @@ getRobotsR = return $ RepPlain $ toContent ("User-agent: *" :: ByteString)
|
|||||||
-- performs initialization and creates a WAI application. This is also the
|
-- performs initialization and creates a WAI application. This is also the
|
||||||
-- place to put your migrate statements to have automatic database
|
-- place to put your migrate statements to have automatic database
|
||||||
-- migrations handled by Yesod.
|
-- migrations handled by Yesod.
|
||||||
with~sitearg~ :: AppEnvironment -> (Application -> IO a) -> IO a
|
with~sitearg~ :: AppConfig -> (Application -> IO a) -> IO a
|
||||||
with~sitearg~ appEnv f = do
|
with~sitearg~ conf f = do
|
||||||
let h = ~sitearg~ appEnv s
|
let h = ~sitearg~ conf s
|
||||||
toWaiApp h >>= f
|
toWaiApp h >>= f
|
||||||
where
|
where
|
||||||
s = static Settings.staticdir
|
s = static Settings.staticDir
|
||||||
|
|
||||||
|
with~sitearg~LoadConfig :: Settings.AppEnvironment -> (Application -> IO a) -> IO a
|
||||||
|
with~sitearg~LoadConfig env f = do
|
||||||
|
conf <- Settings.loadConfig env
|
||||||
|
withFoobar conf f
|
||||||
|
|
||||||
withDevelApp :: Dynamic
|
withDevelApp :: Dynamic
|
||||||
withDevelApp = toDyn (with~sitearg~ Development :: (Application -> IO ()) -> IO ())
|
withDevelApp = do
|
||||||
|
toDyn ((with~sitearg~LoadConfig Settings.Development):: (Application -> IO ()) -> IO ())
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import ~sitearg~
|
|||||||
|
|
||||||
-- This is a handler function for the GET request method on the RootR
|
-- This is a handler function for the GET request method on the RootR
|
||||||
-- resource pattern. All of your resource patterns are defined in
|
-- resource pattern. All of your resource patterns are defined in
|
||||||
-- ~sitearg~.hs; look for the line beginning with mkYesodData.
|
-- config/routes
|
||||||
--
|
--
|
||||||
-- The majority of the code you will write in Yesod lives in these handler
|
-- The majority of the code you will write in Yesod lives in these handler
|
||||||
-- functions. You can spread them across multiple files if you are so
|
-- functions. You can spread them across multiple files if you are so
|
||||||
|
|||||||
@ -60,5 +60,8 @@ executable ~project~
|
|||||||
, wai
|
, wai
|
||||||
, warp
|
, warp
|
||||||
, blaze-builder
|
, blaze-builder
|
||||||
|
, cmdargs
|
||||||
|
, data-object
|
||||||
|
, data-object-yaml
|
||||||
ghc-options: -Wall -threaded
|
ghc-options: -Wall -threaded
|
||||||
|
|
||||||
|
|||||||
@ -12,9 +12,11 @@ module Settings
|
|||||||
, juliusFile
|
, juliusFile
|
||||||
, luciusFile
|
, luciusFile
|
||||||
, widgetFile
|
, widgetFile
|
||||||
, approot
|
, staticRoot
|
||||||
, staticroot
|
, staticDir
|
||||||
, staticdir
|
, loadConfig
|
||||||
|
, AppEnvironment(..)
|
||||||
|
, AppConfig(..)
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import qualified Text.Hamlet as H
|
import qualified Text.Hamlet as H
|
||||||
@ -26,25 +28,55 @@ import Yesod.Widget (addWidget, addCassius, addJulius, addLucius)
|
|||||||
import Data.Monoid (mempty, mappend)
|
import Data.Monoid (mempty, mappend)
|
||||||
import System.Directory (doesFileExist)
|
import System.Directory (doesFileExist)
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
import Data.Object
|
||||||
|
import qualified Data.Object.Yaml as YAML
|
||||||
|
import Control.Monad (join)
|
||||||
|
|
||||||
-- | The base URL for your application. This will usually be different for
|
data AppEnvironment = Test
|
||||||
-- development and production. Yesod automatically constructs URLs for you,
|
| Development
|
||||||
-- so this value must be accurate to create valid links.
|
| Staging
|
||||||
approot :: Text
|
| Production
|
||||||
#ifdef PRODUCTION
|
deriving (Eq, Show, Read, Enum, Bounded)
|
||||||
-- You probably want to change this. If your domain name was "yesod.com",
|
|
||||||
-- you would probably want it to be:
|
-- | Dynamic per-environment configuration loaded from the YAML file Settings.yaml.
|
||||||
-- > approot = "http://www.yesod.com"
|
-- Use dynamic settings to avoid the need to re-compile the application (between staging and production environments).
|
||||||
-- Please note that there is no trailing slash.
|
--
|
||||||
approot = "http://localhost:3000"
|
-- By convention these settings should be overwritten by any command line arguments.
|
||||||
#else
|
-- See config/~sitearg~.hs for command line arguments
|
||||||
approot = "http://localhost:3000"
|
-- Command line arguments provide some convenience but are also required for hosting situations where a setting is read from the environment (appPort on Heroku).
|
||||||
#endif
|
--
|
||||||
|
data AppConfig = AppConfig {
|
||||||
|
appEnv :: AppEnvironment
|
||||||
|
|
||||||
|
, appPort :: Int
|
||||||
|
|
||||||
|
-- | The base URL for your application. This will usually be different for
|
||||||
|
-- development and production. Yesod automatically constructs URLs for you,
|
||||||
|
-- so this value must be accurate to create valid links.
|
||||||
|
-- Please note that there is no trailing slash.
|
||||||
|
--
|
||||||
|
-- You probably want to change this! If your domain name was "yesod.com",
|
||||||
|
-- you would probably want it to be:
|
||||||
|
-- > "http://yesod.com"
|
||||||
|
, appRoot :: Text
|
||||||
|
} deriving (Show)
|
||||||
|
|
||||||
|
loadConfig :: AppEnvironment -> IO AppConfig
|
||||||
|
loadConfig env = do
|
||||||
|
allSettings <- (join $ YAML.decodeFile ("config/settings.yml" :: String)) >>= fromMapping
|
||||||
|
settings <- lookupMapping (show env) allSettings
|
||||||
|
appPortS <- lookupScalar "appPort" settings
|
||||||
|
appRootS <- lookupScalar "appRoot" settings
|
||||||
|
return $ AppConfig {
|
||||||
|
appEnv = env
|
||||||
|
, appPort = read $ appPortS
|
||||||
|
, appRoot = read $ (show appRootS)
|
||||||
|
}
|
||||||
|
|
||||||
-- | The location of static files on your system. This is a file system
|
-- | The location of static files on your system. This is a file system
|
||||||
-- path. The default value works properly with your scaffolded site.
|
-- path. The default value works properly with your scaffolded site.
|
||||||
staticdir :: FilePath
|
staticDir :: FilePath
|
||||||
staticdir = "static"
|
staticDir = "static"
|
||||||
|
|
||||||
-- | The base URL for your static files. As you can see by the default
|
-- | The base URL for your static files. As you can see by the default
|
||||||
-- value, this can simply be "static" appended to your application root.
|
-- value, this can simply be "static" appended to your application root.
|
||||||
@ -59,8 +91,8 @@ staticdir = "static"
|
|||||||
-- have to make a corresponding change here.
|
-- have to make a corresponding change here.
|
||||||
--
|
--
|
||||||
-- To see how this value is used, see urlRenderOverride in ~project~.hs
|
-- To see how this value is used, see urlRenderOverride in ~project~.hs
|
||||||
staticroot :: Text
|
staticRoot :: AppConfig -> Text
|
||||||
staticroot = approot `mappend` "/static"
|
staticRoot conf = (appRoot conf) `mappend` "/static"
|
||||||
|
|
||||||
-- The rest of this file contains settings which rarely need changing by a
|
-- The rest of this file contains settings which rarely need changing by a
|
||||||
-- user.
|
-- user.
|
||||||
|
|||||||
@ -30,7 +30,7 @@ import qualified Data.Text as T
|
|||||||
-- starts running, such as database connections. Every handler will have
|
-- starts running, such as database connections. Every handler will have
|
||||||
-- access to the data present here.
|
-- access to the data present here.
|
||||||
data ~sitearg~ = ~sitearg~
|
data ~sitearg~ = ~sitearg~
|
||||||
{ appEnv :: Settings.AppEnvironment
|
{ settings :: Settings.AppConfig
|
||||||
, getStatic :: Static -- ^ Settings for static file serving.
|
, getStatic :: Static -- ^ Settings for static file serving.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ mkYesodData "~sitearg~" $(parseRoutesFile "config/routes")
|
|||||||
-- Please see the documentation for the Yesod typeclass. There are a number
|
-- Please see the documentation for the Yesod typeclass. There are a number
|
||||||
-- of settings which can be configured by overriding methods here.
|
-- of settings which can be configured by overriding methods here.
|
||||||
instance Yesod ~sitearg~ where
|
instance Yesod ~sitearg~ where
|
||||||
approot _ = Settings.approot
|
approot = Settings.appRoot . settings
|
||||||
|
|
||||||
defaultLayout widget = do
|
defaultLayout widget = do
|
||||||
mmsg <- getMessage
|
mmsg <- getMessage
|
||||||
@ -77,8 +77,8 @@ instance Yesod ~sitearg~ where
|
|||||||
|
|
||||||
-- This is done to provide an optimization for serving static files from
|
-- This is done to provide an optimization for serving static files from
|
||||||
-- a separate domain. Please see the staticroot setting in Settings.hs
|
-- a separate domain. Please see the staticroot setting in Settings.hs
|
||||||
urlRenderOverride a (StaticR s) =
|
urlRenderOverride y (StaticR s) =
|
||||||
Just $ uncurry (joinPath a Settings.staticroot) $ renderRoute s
|
Just $ uncurry (joinPath y (Settings.staticRoot $ settings y)) $ renderRoute s
|
||||||
urlRenderOverride _ _ = Nothing
|
urlRenderOverride _ _ = Nothing
|
||||||
|
|
||||||
-- This function creates static content files in the static folder
|
-- This function creates static content files in the static folder
|
||||||
@ -87,7 +87,7 @@ instance Yesod ~sitearg~ where
|
|||||||
-- users receiving stale content.
|
-- users receiving stale content.
|
||||||
addStaticContent ext' _ content = do
|
addStaticContent ext' _ content = do
|
||||||
let fn = base64md5 content ++ '.' : T.unpack ext'
|
let fn = base64md5 content ++ '.' : T.unpack ext'
|
||||||
let statictmp = Settings.staticdir ++ "/tmp/"
|
let statictmp = Settings.staticDir ++ "/tmp/"
|
||||||
liftIO $ createDirectoryIfMissing True statictmp
|
liftIO $ createDirectoryIfMissing True statictmp
|
||||||
let fn' = statictmp ++ fn
|
let fn' = statictmp ++ fn
|
||||||
exists <- liftIO $ doesFileExist fn'
|
exists <- liftIO $ doesFileExist fn'
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
user <- lookupScalar "user"
|
connPart <- fmap concat $ (flip mapM) ["user", "password", "host", "port"] $ \key -> do
|
||||||
password <- lookupScalar "user"
|
value <- lookupScalar key settings
|
||||||
host <- lookupScalar "host"
|
return $ append (snoc (pack key) '=') (snoc value ' ')
|
||||||
port <- lookupScalar "port"
|
return $ append connPart (append " dbname= " database)
|
||||||
return $ "user=" ++ user ++ "password=" ++ password ++ "host=" ++ host ++ "port=" ++ port ++ "dbname= ++ database"
|
|
||||||
|
|||||||
@ -7,24 +7,20 @@ import System.Console.CmdArgs
|
|||||||
import Data.Char (toUpper, toLower)
|
import Data.Char (toUpper, toLower)
|
||||||
|
|
||||||
#if PRODUCTION
|
#if PRODUCTION
|
||||||
main :: IO ()
|
|
||||||
main = do
|
|
||||||
args <- cmdArgs argConfig
|
|
||||||
appEnv <- getAppEnv args
|
|
||||||
config <- Settings.loadConfig appEnv
|
|
||||||
let c = if (port args) /= 0 then config {appPort = (port args) } else config
|
|
||||||
with~sitearg~ c $ run (appPort c)
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
import System.IO (hPutStrLn, stderr)
|
import System.IO (hPutStrLn, stderr)
|
||||||
import Network.Wai.Middleware.Debug (debug)
|
import Network.Wai.Middleware.Debug (debug)
|
||||||
|
#endif
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
args <- cmdArgs argConfig
|
args <- cmdArgs argConfig
|
||||||
appEnv <- getAppEnv args
|
appEnv <- getAppEnv args
|
||||||
config <- Settings.loadConfig appEnv
|
config <- Settings.loadConfig appEnv
|
||||||
let c = if (port args) /= 0 then config {appPort = (port args) } else config
|
let c = if (port args) /= 0 then config {appPort = (port args) } else config
|
||||||
|
#if PRODUCTION
|
||||||
|
with~sitearg~ c $ run (appPort c)
|
||||||
|
#else
|
||||||
hPutStrLn stderr $ (show appEnv) ++ " application launched, listening on port " ++ show (appPort c)
|
hPutStrLn stderr $ (show appEnv) ++ " application launched, listening on port " ++ show (appPort c)
|
||||||
with~sitearg~ c $ run (appPort c) . debug
|
with~sitearg~ c $ run (appPort c) . debug
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
4
tests/mini-input.txt
Normal file
4
tests/mini-input.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
Michael
|
||||||
|
foobar
|
||||||
|
Foobar
|
||||||
|
m
|
||||||
4
tests/postgresql-input.txt
Normal file
4
tests/postgresql-input.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
Michael
|
||||||
|
foobar
|
||||||
|
Foobar
|
||||||
|
p
|
||||||
@ -1,4 +1,3 @@
|
|||||||
#!/bin/sh
|
#!/bin/bash -x
|
||||||
|
|
||||||
cabal clean && cabal install &&
|
rm -rf foobar && runghc scaffold.hs init && cd foobar && cabal install && cabal install -fdevel && cd ..
|
||||||
rm -rf foobar && runghc scaffold.hs init < tests/sample-input.txt && cd foobar && cabal install && cabal install -fdevel && cd ..
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user