package cli import ( "fmt" "log/slog" "git.avsdev.uk/Go/job-search/internal/config" "git.avsdev.uk/Go/job-search/internal/logging" "github.com/spf13/cobra" ) // Options holds the flags shared by every command. Bind registers them on the // root command and RunSetup acts on them. type Options struct { configFile string debug bool quiet bool } // Bind registers the shared flags as persistent flags on the root command cmd. func (o *Options) Bind(cmd *cobra.Command) { pf := cmd.PersistentFlags() pf.StringVarP(&o.configFile, "config", "c", "", "configuration file") pf.BoolVarP(&o.debug, "debug", "d", false, "enable debug messages") pf.BoolVarP( &o.quiet, "quiet", "q", false, "don't report info or warning messages", ) } // RunSetup prepares a command to run and returns its configuration. When // loadConfig is true it loads the configuration (from the --config file if // given), with --debug and --quiet overriding its log level, and then, unless // terminalLog is true, switches logging to the configured log file (staying // on the terminal, with a warning, if none is configured). func (o *Options) RunSetup( cmd *cobra.Command, loadConfig bool, terminalLog bool, ) (*config.JobSearchConfig, error) { // Flags and arguments are valid from here on, so errors are runtime // failures: report them without cobra's usage text. cmd.SilenceUsage = true // Check for debug level or quiet supression via args conf := &config.JobSearchConfig{ Logging: config.JobSearchConfigLogging{}, } if o.debug { conf.Logging.Level = "debug" } else if o.quiet { conf.Logging.Level = "error" } // Only load config if command requests it (nearly always true) if loadConfig { // Load config - from specified file if provided if err := config.Init(o.configFile, conf); err != nil { return nil, err } // Change logging level based off newly loaded config if conf.Logging.LogLevel() <= slog.LevelDebug && !logging.IsDebugEnabled() { logging.EnableDebug() } // Check if the logging should be switched to file if !terminalLog { if len(conf.Logging.File) == 0 { slog.Warn("No log file configured, remaining in console logging mode!") } else if err := logging.LogToFile(conf.Logging.File); err != nil { return nil, fmt.Errorf("opening log file: %w", err) } } } return conf, nil } // Finish shuts down any open file logger func (o *Options) Finish() error { if logging.IsFileLogger() { return logging.Shutdown() } return nil }