- New LogLevel type: Debug, Info, Warn, Error with Ord instance - Logger holds configured level and output handle (stderr or file) - --log-level and --log-file CLI flags - log_level and log_file YAML config fields - Log messages assigned appropriate severity levels - Test logger updated to new Logger structure - All 17 tests passing
This commit is contained in:
+49
-15
@@ -3,6 +3,7 @@ module Main (main) where
|
||||
import Converge
|
||||
import Data.Maybe (fromMaybe)
|
||||
import Data.Text (Text)
|
||||
import qualified Data.Text as T
|
||||
import Options.Applicative
|
||||
import System.IO (hPutStrLn, stderr)
|
||||
|
||||
@@ -17,6 +18,10 @@ data CliArgs = CliArgs
|
||||
-- ^ Branch name (used only in single-repo mode).
|
||||
, cliDebounce :: !(Maybe Int)
|
||||
-- ^ Debounce override for both modes.
|
||||
, cliLogLevel :: !(Maybe LogLevel)
|
||||
-- ^ Log level override.
|
||||
, cliLogFile :: !(Maybe FilePath)
|
||||
-- ^ Log file path.
|
||||
}
|
||||
|
||||
cliParser :: Parser CliArgs
|
||||
@@ -62,6 +67,26 @@ cliParser =
|
||||
<> help "Debounce window in milliseconds (overrides config file)"
|
||||
)
|
||||
)
|
||||
<*> optional
|
||||
( option
|
||||
(maybeReader (\s -> case T.toLower (T.pack s) of
|
||||
"debug" -> Just Debug
|
||||
"info" -> Just Info
|
||||
"warn" -> Just Warn
|
||||
"error" -> Just Error
|
||||
_ -> Nothing))
|
||||
( long "log-level"
|
||||
<> metavar "LEVEL"
|
||||
<> help "Minimum log level: debug, info, warn, or error (default: info)"
|
||||
)
|
||||
)
|
||||
<*> optional
|
||||
( strOption
|
||||
( long "log-file"
|
||||
<> metavar "FILE"
|
||||
<> help "Write logs to a file instead of stderr"
|
||||
)
|
||||
)
|
||||
|
||||
parserInfo :: ParserInfo CliArgs
|
||||
parserInfo =
|
||||
@@ -79,7 +104,7 @@ main = do
|
||||
(options, configSource) <- case cliConfig cli of
|
||||
Just cfgPath -> do
|
||||
cfg <- loadConfig cfgPath
|
||||
let opts = applyDebounce mDebounceOverride (configToOptions cfg)
|
||||
let opts = applyOverrides mDebounceOverride (cliLogLevel cli) (cliLogFile cli) (configToOptions cfg)
|
||||
pure (opts, Just cfgPath)
|
||||
Nothing -> do
|
||||
exists <- configFileExists
|
||||
@@ -87,20 +112,21 @@ main = do
|
||||
then do
|
||||
cfgPath <- defaultConfigPath
|
||||
cfg <- loadConfig cfgPath
|
||||
let opts = applyDebounce mDebounceOverride (configToOptions cfg)
|
||||
let opts = applyOverrides mDebounceOverride (cliLogLevel cli) (cliLogFile cli) (configToOptions cfg)
|
||||
pure (opts, Just cfgPath)
|
||||
else
|
||||
pure
|
||||
( defaultOptions
|
||||
{ optRepos =
|
||||
[ defaultRepoConfig
|
||||
{ rcPath = fromMaybe "." (cliRepo cli)
|
||||
, rcRemote = cliRemote cli
|
||||
, rcBranch = cliBranch cli
|
||||
}
|
||||
]
|
||||
, optDebounceMs = fromMaybe 5000 mDebounceOverride
|
||||
}
|
||||
( applyOverrides mDebounceOverride (cliLogLevel cli) (cliLogFile cli)
|
||||
defaultOptions
|
||||
{ optRepos =
|
||||
[ defaultRepoConfig
|
||||
{ rcPath = fromMaybe "." (cliRepo cli)
|
||||
, rcRemote = cliRemote cli
|
||||
, rcBranch = cliBranch cli
|
||||
}
|
||||
]
|
||||
, optDebounceMs = fromMaybe 5000 mDebounceOverride
|
||||
}
|
||||
, Nothing
|
||||
)
|
||||
case configSource of
|
||||
@@ -118,6 +144,14 @@ main = do
|
||||
mapM_ (\r -> hPutStrLn stderr (" - " <> rcPath r)) (optRepos options)
|
||||
runConverge options
|
||||
|
||||
applyDebounce :: Maybe Int -> Options -> Options
|
||||
applyDebounce (Just ms) opts = opts{optDebounceMs = ms}
|
||||
applyDebounce Nothing opts = opts
|
||||
|
||||
-- | Apply CLI overrides (debounce, log level, log file) to Options.
|
||||
applyOverrides :: Maybe Int -> Maybe LogLevel -> Maybe FilePath -> Options -> Options
|
||||
applyOverrides mDebounce mLogLevel mLogFile opts =
|
||||
opts
|
||||
{ optDebounceMs = maybe (optDebounceMs opts) id mDebounce
|
||||
, optLogLevel = fromMaybe (optLogLevel opts) mLogLevel
|
||||
, optLogFile = case mLogFile of
|
||||
Just _ -> mLogFile -- CLI --log-file overrides config
|
||||
Nothing -> optLogFile opts
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user