Files
roux/app/Main.hs
T

95 lines
3.2 KiB
Haskell

{-# LANGUAGE OverloadedStrings #-}
{- | Entry point for the Roux recipe server.
Starts a Warp HTTP server and serves recipe content.
-}
module Main (main) where
import Data.String (fromString)
import qualified Network.Wai.Handler.Warp as Warp
import qualified Options.Applicative as Opts
import System.IO (BufferMode (NoBuffering), hSetBuffering, stderr, stdout)
import qualified Roux
import qualified Roux.Config as Config
-- ---------------------------------------------------------------------------
-- CLI options
-- ---------------------------------------------------------------------------
data Options = Options
{ optHost :: String
, optPort :: Int
, optRecipeDir :: FilePath
, optConfigFile :: FilePath
}
optionsParser :: Opts.Parser Options
optionsParser =
Options
<$> Opts.strOption
( Opts.long "host"
<> Opts.metavar "HOST"
<> Opts.help "Listen host"
<> Opts.value "0.0.0.0"
<> Opts.showDefault
)
<*> Opts.option
Opts.auto
( Opts.long "port"
<> Opts.short 'p'
<> Opts.metavar "PORT"
<> Opts.help "Listen port"
<> Opts.value 8080
<> Opts.showDefault
)
<*> Opts.strOption
( Opts.long "recipe-dir"
<> Opts.short 'r'
<> Opts.metavar "DIR"
<> Opts.help "Path to directory containing Cooklang recipe files"
<> Opts.value "recipes"
<> Opts.showDefault
)
<*> Opts.strOption
( Opts.long "config-file"
<> Opts.metavar "FILE"
<> Opts.help "Path to YAML configuration file"
<> Opts.value "roux-config.yaml"
<> Opts.showDefault
)
main :: IO ()
main = do
-- Disable buffering so Docker sees log output immediately.
hSetBuffering stdout NoBuffering
hSetBuffering stderr NoBuffering
opts <-
Opts.execParser $
Opts.info
(optionsParser Opts.<**> Opts.helper)
( Opts.fullDesc
<> Opts.progDesc "Roux recipe management server"
<> Opts.header "roux-server — personal/family recipe manager"
)
let settings =
Warp.setPort (optPort opts) $
Warp.setHost
(fromString (optHost opts))
Warp.defaultSettings
putStrLn $ "[roux] scanning recipes from " <> optRecipeDir opts
putStrLn $ "[roux] listening on " <> optHost opts <> ":" <> show (optPort opts)
putStrLn $ "[roux] config file: " <> optConfigFile opts
-- Load config (file may be missing; LLM features disabled gracefully)
configResult <- Config.loadConfig (optConfigFile opts)
let config = case configResult of
Right cfg -> cfg
Left _ -> Config.RouxConfig Nothing
case configResult of
Left err -> putStrLn $ "[roux] warning: " <> err <> " — LLM features disabled"
Right _ -> pure ()
waiApp <- Roux.app (optRecipeDir opts) config
Warp.runSettings settings waiApp