/* Copyright © 2026 Craig Williams This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ package cmd import ( "log/slog" "os" "strings" "git.avsdev.uk/Go/job-search/internal/cli" cmdConfig "git.avsdev.uk/Go/job-search/internal/cli/config" cmdVersion "git.avsdev.uk/Go/job-search/internal/cli/version" "git.avsdev.uk/Go/job-search/internal/config" "git.avsdev.uk/Go/job-search/internal/log" "github.com/spf13/cobra" ) var rootCmd = &cobra.Command{ Use: "job-search", Short: "JobSearch - AVSDev Future Opportunities!", Long: `JobSearch is a scraping tool for searching for possible contract opportunities. `, CompletionOptions: cobra.CompletionOptions{ HiddenDefaultCmd: true, }, PersistentPreRunE: func(cmd *cobra.Command, args []string) error { // Check if the command is expecting to use terminal for messages if val, ok := cmd.Annotations["terminal_log"]; ok && val == "1" { log.LogToTerminal() } // Check for debug level via args dbgCount, _ := cmd.Flags().GetCount("debug") conf := config.JobSearchConfig{ Logging: config.JobSearchConfigLogging{}, } if dbgCount > 1 { conf.Logging.Level = "debug" } else if dbgCount > 0 { conf.Logging.Level = "info" } if conf.Logging.LogLevel() <= slog.LevelDebug { log.EnableDebug() } else if conf.Logging.LogLevel() <= slog.LevelInfo { log.EnableInfo() } // With logging set up, these will be visible if trace is active slog.Debug("root.PersistentPreRun") slog.Debug( "command: \"" + strings.Join(strings.Split(cmd.CommandPath(), " ")[1:], " ") + "\"", ) // Always load config unless command indicates not to if val, ok := cmd.Annotations["no_config"]; !ok || val == "0" { // Load config - from specified file if provided cfgFile, _ := cmd.Flags().GetString("config") if err := config.Init(cfgFile, &conf); err != nil { return err } // Attach config to command context ctx := cli.WithConfig(cmd.Context(), conf) cmd.SetContext(ctx) // Change logging level based off newly loaded config if conf.Logging.LogLevel() <= slog.LevelDebug { log.EnableDebug() } } return nil }, PersistentPostRun: func(cmd *cobra.Command, args []string) { slog.Debug("root.PersistentPostRun") }, } // Execute, called by main.main() handles all child commands and appropriate // flags. func Execute() { err := rootCmd.Execute() if err != nil { os.Exit(1) } } func init() { cobra.EnableTraverseRunHooks = true log.Init() pFlags := rootCmd.PersistentFlags() pFlags.StringP( "config", "c", "", "config file (default: "+config.EtcConfigPath+"/config.yaml)") pFlags.CountP("debug", "d", "enable debug output (repeat for trace)") rootCmd.AddCommand(cmdVersion.NewCommand()) rootCmd.AddCommand(cmdConfig.NewCommand()) }