Update scaffold for defaultMain

This commit is contained in:
patrick brisbin 2011-09-10 23:33:17 -04:00
parent b5a3bd4671
commit 63d34a3bb4
8 changed files with 14 additions and 189 deletions

View File

@ -95,8 +95,8 @@ scaffold = do
Tiny -> "" Tiny -> ""
settingsTextImport = case backend of settingsTextImport = case backend of
Postgresql -> "import Data.Text (Text, pack, concat)\nimport Prelude hiding (concat)" Postgresql -> "import Data.Text (Text, concat)\nimport Prelude hiding (concat)"
_ -> "import Data.Text (Text, pack)" _ -> "import Data.Text (Text)"
packages = packages =
if backend == MongoDB if backend == MongoDB

View File

@ -68,7 +68,7 @@ withDevelAppPort =
where where
go :: ((Int, Application) -> IO ()) -> IO () go :: ((Int, Application) -> IO ()) -> IO ()
go f = do go f = do
conf <- Settings.loadConfig Settings.Development conf <- loadConfig Development
let port = appPort conf let port = appPort conf
logger <- makeLogger logger <- makeLogger
logString logger $ "Devel application launched, listening on port " ++ show port logString logger $ "Devel application launched, listening on port " ++ show port

View File

@ -45,7 +45,7 @@ import Text.Shakespeare.Text (stext)
-- 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~
{ settings :: Settings.AppConfig { settings :: AppConfig
, getLogger :: Logger , getLogger :: Logger
, getStatic :: Static -- ^ Settings for static file serving. , getStatic :: Static -- ^ Settings for static file serving.
, connPool :: Settings.ConnectionPool -- ^ Database connection pool. , connPool :: Settings.ConnectionPool -- ^ Database connection pool.
@ -75,7 +75,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 . settings approot = appRoot . settings
-- Place the session key file in the config folder -- Place the session key file in the config folder
encryptKey _ = fmap Just $ getKey "config/client_session_key.aes" encryptKey _ = fmap Just $ getKey "config/client_session_key.aes"

View File

@ -18,9 +18,6 @@ module Settings
, runConnectionPool , runConnectionPool
, staticRoot , staticRoot
, staticDir , staticDir
, loadConfig
, AppEnvironment(..)
, AppConfig(..)
) where ) where
import qualified Text.Hamlet as S import qualified Text.Hamlet as S
@ -32,6 +29,7 @@ import Text.Shakespeare.Text (st)
import Language.Haskell.TH.Syntax import Language.Haskell.TH.Syntax
import Database.Persist.~importPersist~ import Database.Persist.~importPersist~
import Yesod (liftIO, MonadControlIO, addWidget, addCassius, addJulius, addLucius, whamletFile) import Yesod (liftIO, MonadControlIO, addWidget, addCassius, addJulius, addLucius, whamletFile)
import Yesod.Settings
import Data.Monoid (mempty) import Data.Monoid (mempty)
import System.Directory (doesFileExist) import System.Directory (doesFileExist)
~settingsTextImport~ ~settingsTextImport~
@ -39,68 +37,6 @@ 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)
data AppEnvironment = Test
| Development
| Staging
| Production
deriving (Eq, Show, Read, Enum, Bounded)
-- | Dynamic per-environment configuration loaded from the YAML file Settings.yaml.
-- Use dynamic settings to avoid the need to re-compile the application (between staging and production environments).
--
-- By convention these settings should be overwritten by any command line arguments.
-- See config/Foundation.hs for command line arguments
-- Command line arguments provide some convenience but are also required for hosting situations where a setting is read from the environment (appPort on Heroku).
--
data AppConfig = AppConfig {
appEnv :: AppEnvironment
, appPort :: Int
-- | Your application will keep a connection pool and take connections from
-- there as necessary instead of continually creating new connections. This
-- value gives the maximum number of connections to be open at a given time.
-- If your application requests a connection when all connections are in
-- use, that request will fail. Try to choose a number that will work well
-- with the system resources available to you while providing enough
-- connections for your expected load.
--
-- Connections are returned to the pool as quickly as possible by
-- Yesod to avoid resource exhaustion. A connection is only considered in
-- use while within a call to runDB.
, connectionPoolSize :: 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
hostS <- lookupScalar "host" settings
port <- fmap read $ lookupScalar "port" settings
connectionPoolSizeS <- lookupScalar "connectionPoolSize" settings
return $ AppConfig {
appEnv = env
, appPort = port
, appRoot = pack $ hostS ++ addPort port
, connectionPoolSize = read connectionPoolSizeS
}
where
addPort :: Int -> String
#ifdef PRODUCTION
addPort _ = ""
#else
addPort p = ":" ++ (show p)
#endif
-- Static setting below. Changing these requires a recompile -- Static setting below. Changing these requires a recompile

View File

@ -1,68 +1,5 @@
{-# LANGUAGE CPP, DeriveDataTypeable #-} import Yesod.Main (defaultMain)
import Settings (AppEnvironment(..), AppConfig(..), loadConfig)
import Application (with~sitearg~) import Application (with~sitearg~)
import Network.Wai.Handler.Warp (run)
import System.Console.CmdArgs hiding (args)
import Data.Char (toUpper, toLower)
#ifndef PRODUCTION
import Network.Wai.Middleware.Debug (debugHandle)
import Yesod.Logger (logString, logLazyText, flushLogger, makeLogger)
#else
import Yesod.Logger (makeLogger)
#endif
main :: IO () main :: IO ()
main = do main = defaultMain with~sitearg~
logger <- makeLogger
args <- cmdArgs argConfig
env <- getAppEnv args
config <- loadConfig env
let c = if port args /= 0
then config { appPort = port args }
else config
#if PRODUCTION
with~sitearg~ c logger $ run (appPort c)
#else
logString logger $ (show env) ++ " application launched, listening on port " ++ show (appPort c)
with~sitearg~ c logger $ run (appPort c) . debugHandle (logHandle logger)
flushLogger logger
where
logHandle logger msg = logLazyText logger msg >> flushLogger logger
#endif
data ArgConfig = ArgConfig
{ environment :: String
, port :: Int
} deriving (Show, Data, Typeable)
argConfig :: ArgConfig
argConfig = ArgConfig
{ environment = def
&= help ("application environment, one of: " ++ (foldl1 (\a b -> a ++ ", " ++ b) environments))
&= typ "ENVIRONMENT"
, port = def
&= typ "PORT"
}
environments :: [String]
environments = map ((map toLower) . show) ([minBound..maxBound] :: [AppEnvironment])
-- | retrieve the -e environment option
getAppEnv :: ArgConfig -> IO AppEnvironment
getAppEnv cfg = do
let e = if environment cfg /= ""
then environment cfg
else
#if PRODUCTION
"production"
#else
"development"
#endif
return $ read $ capitalize e
where
capitalize [] = []
capitalize (x:xs) = toUpper x : map toLower xs

View File

@ -11,6 +11,7 @@ module Application
import Foundation import Foundation
import Settings import Settings
import Yesod.Static import Yesod.Static
import Yesod.Settings
import Yesod.Logger (makeLogger, flushLogger, Logger, logLazyText, logString) import Yesod.Logger (makeLogger, flushLogger, Logger, logLazyText, logString)
import Data.ByteString (ByteString) import Data.ByteString (ByteString)
import Network.Wai (Application) import Network.Wai (Application)
@ -54,7 +55,7 @@ withDevelAppPort =
where where
go :: ((Int, Application) -> IO ()) -> IO () go :: ((Int, Application) -> IO ()) -> IO ()
go f = do go f = do
conf <- Settings.loadConfig Settings.Development conf <- loadConfig Development
let port = appPort conf let port = appPort conf
logger <- makeLogger logger <- makeLogger
logString logger $ "Devel application launched, listening on port " ++ show port logString logger $ "Devel application launched, listening on port " ++ show port

View File

@ -14,6 +14,7 @@ module Foundation
) where ) where
import Yesod.Core import Yesod.Core
import Yesod.Settings (AppConfig(..))
import Yesod.Static (Static, base64md5, StaticRoute(..)) import Yesod.Static (Static, base64md5, StaticRoute(..))
import Settings.StaticFiles import Settings.StaticFiles
import Yesod.Logger (Logger, logLazyText) import Yesod.Logger (Logger, logLazyText)
@ -32,7 +33,7 @@ import Web.ClientSession (getKey)
-- 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~
{ settings :: Settings.AppConfig { settings :: AppConfig
, getLogger :: Logger , getLogger :: Logger
, getStatic :: Static -- ^ Settings for static file serving. , getStatic :: Static -- ^ Settings for static file serving.
} }
@ -61,7 +62,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 . settings approot = appRoot . settings
-- Place the session key file in the config folder -- Place the session key file in the config folder
encryptKey _ = fmap Just $ getKey "config/client_session_key.aes" encryptKey _ = fmap Just $ getKey "config/client_session_key.aes"

View File

@ -14,9 +14,6 @@ module Settings
, widgetFile , widgetFile
, staticRoot , staticRoot
, staticDir , staticDir
, loadConfig
, AppEnvironment(..)
, AppConfig(..)
) where ) where
import qualified Text.Hamlet as S import qualified Text.Hamlet as S
@ -27,6 +24,7 @@ import qualified Text.Shakespeare.Text as S
import Text.Shakespeare.Text (st) import Text.Shakespeare.Text (st)
import Language.Haskell.TH.Syntax import Language.Haskell.TH.Syntax
import Yesod.Widget (addWidget, addCassius, addJulius, addLucius, whamletFile) import Yesod.Widget (addWidget, addCassius, addJulius, addLucius, whamletFile)
import Yesod.Settings
import Data.Monoid (mempty) import Data.Monoid (mempty)
import System.Directory (doesFileExist) import System.Directory (doesFileExist)
~settingsTextImport~ ~settingsTextImport~
@ -34,54 +32,6 @@ 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)
data AppEnvironment = Test
| Development
| Staging
| Production
deriving (Eq, Show, Read, Enum, Bounded)
-- | Dynamic per-environment configuration loaded from the YAML file Settings.yaml.
-- Use dynamic settings to avoid the need to re-compile the application (between staging and production environments).
--
-- By convention these settings should be overwritten by any command line arguments.
-- See config/~sitearg~.hs for command line arguments
-- Command line arguments provide some convenience but are also required for hosting situations where a setting is read from the environment (appPort on Heroku).
--
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
hostS <- lookupScalar "host" settings
port <- fmap read $ lookupScalar "port" settings
return $ AppConfig {
appEnv = env
, appPort = port
, appRoot = pack $ hostS ++ addPort port
}
where
addPort :: Int -> String
#ifdef PRODUCTION
addPort _ = ""
#else
addPort p = ":" ++ (show p)
#endif
-- | 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