packages feed

baikai-agent-0.1.0.0: app/Main.hs

-- | The @baikai@ executable.
--
-- Deliberately thin. Everything real lives in "Baikai.Agent.Cli", which
-- returns an 'AgentCliRun' rather than writing to streams or exiting, so
-- the whole command-line surface is reachable from the test suite
-- without spawning this binary. This module's only job is to interpret
-- that record into real streams and a real exit code.
module Main (main) where

import Baikai.Agent.Cli
  ( AgentCliRun,
    agentCliParserInfo,
    runAgentCli,
  )
import Control.Lens ((^.))
import Data.Generics.Labels ()
import Data.Text qualified as Text
import Data.Text.IO qualified as TextIO
import Options.Applicative qualified as Options
import Settei.Env (EnvSnapshot, envSnapshot)
import System.Environment (getEnvironment)
import System.Exit (ExitCode (..), exitWith)
import System.IO (stderr, stdout)

main :: IO ()
main = do
  options <- Options.execParser agentCliParserInfo
  snapshot <- captureEnvironment
  finished <- runAgentCli snapshot options
  emit finished
  exitWith (exitCodeFrom (finished ^. #exitCode))

-- | Snapshot the real environment once. @settei@ takes the snapshot as
-- a value rather than reading the environment itself, which is what
-- makes the layer testable without mutating the process.
captureEnvironment :: IO EnvSnapshot
captureEnvironment = do
  values <- getEnvironment
  pure (envSnapshot [(Text.pack name, Text.pack value) | (name, value) <- values])

emit :: AgentCliRun -> IO ()
emit finished = do
  TextIO.hPutStr stdout (finished ^. #standardOutput)
  TextIO.hPutStr stderr (finished ^. #standardError)

exitCodeFrom :: Int -> ExitCode
exitCodeFrom 0 = ExitSuccess
exitCodeFrom code = ExitFailure code