Make app configurable via environment vars

This commit is contained in:
Correl Roush 2022-03-28 02:05:32 -04:00
parent 492b4fa71b
commit f35b1e0b18
6 changed files with 50 additions and 21 deletions

View file

@ -1,10 +1,10 @@
module Main where
import Data.Maybe
import System.Environment
import System.Envy (decodeWithDefaults)
import Tutor
import Tutor.Config
main :: IO ()
main = do
dbFile <- lookupEnv "TUTOR_DATABASE"
startApp (fromMaybe "tutor.db" dbFile)
config <- decodeWithDefaults defaultConfig :: IO Config
startApp config

View file

@ -22,6 +22,7 @@ dependencies:
- base >= 4.7 && < 5
- aeson
- containers
- envy
- lens
- openapi3
- parsec

View file

@ -4,11 +4,14 @@ import Network.Wai.Handler.Warp
import Network.Wai.Logger
import Servant (serve)
import Tutor.Api (app)
import Tutor.Config
import Tutor.Database (initDb)
startApp :: FilePath -> IO ()
startApp dbFile = do
initDb dbFile
startApp :: Config -> IO ()
startApp config = do
initDb (tutorDatabase config)
withStdoutLogger $
\logger ->
runSettings (setPort 8080 $ setLogger logger $ defaultSettings) (app dbFile)
runSettings
(setPort (tutorPort config) $ setLogger logger $ defaultSettings)
(app config)

View file

@ -28,6 +28,7 @@ import qualified Paths_tutor as PT
import Servant
import Servant.OpenApi (HasOpenApi (toOpenApi))
import Tutor.Card
import Tutor.Config
import Tutor.Database
data Status = Status
@ -194,8 +195,8 @@ openapi =
& info . description ?~ "An API for searching a Magic: The Gathering card collection."
& info . license ?~ ("MIT" & url ?~ URL "http://mit.com")
tutorServer :: FilePath -> Server TutorAPI
tutorServer dbFile = status :<|> searchCards dbFile
tutorServer :: Config -> Server TutorAPI
tutorServer config = status :<|> searchCards (tutorDatabase config)
where
searchCards :: FilePath -> Maybe T.Text -> Maybe T.Text -> Maybe T.Text -> Handler [Card]
searchCards dbFile q sortBy inCollection =
@ -204,11 +205,11 @@ tutorServer dbFile = status :<|> searchCards dbFile
docsServer :: Server DocsAPI
docsServer = return openapi
elmServer :: Server ElmAPI
elmServer = serveDirectoryFileServer "www/public"
elmServer :: FilePath -> Server ElmAPI
elmServer = serveDirectoryFileServer
server :: FilePath -> Server API
server dbFile = tutorServer dbFile :<|> docsServer :<|> elmServer
server :: Config -> Server API
server config = tutorServer config :<|> docsServer :<|> elmServer (tutorStatic config)
packageVersion :: T.Text
packageVersion = T.pack $ showVersion PT.version
@ -220,5 +221,5 @@ status =
{ apiVersion = packageVersion
}
app :: FilePath -> Application
app dbFile = serve api $ server dbFile
app :: Config -> Application
app config = serve api $ server config

22
src/Tutor/Config.hs Normal file
View file

@ -0,0 +1,22 @@
{-# LANGUAGE DeriveGeneric #-}
module Tutor.Config (Config (..), defaultConfig) where
import GHC.Generics
import System.Envy
data Config = Config
{ tutorPort :: Int,
tutorDatabase :: FilePath,
tutorStatic :: FilePath
}
deriving (Generic, Show)
defaultConfig =
Config
{ tutorPort = 8000,
tutorDatabase = "tutor.db",
tutorStatic = "www/public"
}
instance FromEnv Config

View file

@ -3,9 +3,11 @@
module AppSpec (spec) where
import Database.SQLite.Simple (execute_, withConnection)
import System.Envy (decodeWithDefaults)
import Test.Hspec
import Test.Hspec.Wai
import Tutor.Api (app)
import Tutor.Config
import Tutor.Database (initDb)
spec :: Spec
@ -15,12 +17,12 @@ spec = do
it "responds with 200" $ do
get "/search" `shouldRespondWith` 200
where
dbFile = "test.db"
startApp = do
initDb dbFile
resetDb
return $ app dbFile
resetDb = do
config <- decodeWithDefaults (defaultConfig {tutorDatabase = "test.db"}) :: IO Config
initDb (tutorDatabase config)
resetDb (tutorDatabase config)
return $ app config
resetDb dbFile = do
withConnection dbFile $ \conn ->
mapM_
(execute_ conn)