/* 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 . */ // Command fetcher, for fetching opportunities from JobSearch's sources. Run // `fetcher --help` for usage. package main import ( "fmt" "log/slog" "os" "strings" "github.com/spf13/cobra" "git.avsdev.uk/Go/job-search/internal/cli" "git.avsdev.uk/Go/job-search/internal/cli/fetch" ) // newRootCmd builds the command tree. It returns a fresh tree on each call so // tests can run commands in isolation. func newRootCmd() *cobra.Command { opts := &cli.Options{} root := &cobra.Command{ Use: "fetcher", Short: "Fetch tools for JobSearch", Long: `fetcher fetches from Find a Tender once and prints the releases as JSON (fts-once), or polls every enabled source on its interval until stopped (service). It reads the JobSearch configuration. `, SilenceUsage: true, // don't print usage on runtime errors SilenceErrors: true, // main prints the error once CompletionOptions: cobra.CompletionOptions{ HiddenDefaultCmd: true, }, PersistentPreRunE: func(cmd *cobra.Command, args []string) error { cli.SetupInitialLogging(cmd) slog.Debug("command persistent pre-run", "command", "root") slog.Debug( "command", "path", strings.Join(strings.Split(cmd.CommandPath(), " ")[1:], " "), ) return nil }, PersistentPostRunE: func(cmd *cobra.Command, args []string) error { slog.Debug("command persistent post-run", "command", "root") return opts.Finish() }, } cobra.EnableTraverseRunHooks = true opts.Bind(root) root.AddCommand(fetch.NewCommands(opts)...) return root } func main() { if err := newRootCmd().Execute(); err != nil { fmt.Fprintln(os.Stderr, "fetcher:", err) os.Exit(1) } }