Short and single-letter names in application code become full words (tests keep theirs). Wrapped calls, signatures and composite literals put one item per line, and one-line function bodies are expanded. Exported names and groups of constants get doc comments, and comments refer to the renamed identifiers.
93 lines
2.4 KiB
Go
93 lines
2.4 KiB
Go
package config
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"log/slog"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/spf13/cobra"
|
|
"github.com/spf13/viper"
|
|
|
|
"git.avsdev.uk/Go/job-search/internal/config"
|
|
)
|
|
|
|
func commandInit() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "init [config_path]",
|
|
Args: cobra.MatchAll(cobra.MinimumNArgs(0), cobra.MaximumNArgs(1)),
|
|
Short: "Create an empty configuration file",
|
|
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
|
slog.Debug("command persistent pre-run", "command", "config.init")
|
|
},
|
|
PersistentPostRun: func(cmd *cobra.Command, args []string) {
|
|
slog.Debug("command persistent post-run", "command", "config.init")
|
|
},
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
slog.Debug("command run", "command", "config.init")
|
|
|
|
if err := cobra.MinimumNArgs(0)(cmd, args); err != nil {
|
|
return err
|
|
}
|
|
if err := cobra.MaximumNArgs(1)(cmd, args); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Flags and arguments are valid from here on, so errors are runtime
|
|
// failures: report them without cobra's usage text.
|
|
cmd.SilenceUsage = true
|
|
|
|
// With no path, the default locations are used.
|
|
cfgFile := ""
|
|
if len(args) > 0 {
|
|
cfgFile = strings.TrimSpace(args[0])
|
|
}
|
|
if cfgFile != "" {
|
|
// Use the config file given.
|
|
viper.SetConfigFile(cfgFile)
|
|
} else {
|
|
// Search config in /etc or local directory.
|
|
viper.AddConfigPath(config.EtcConfigPath)
|
|
viper.AddConfigPath(".")
|
|
viper.SetConfigName("config")
|
|
}
|
|
|
|
err := viper.ReadInConfig()
|
|
if err == nil {
|
|
return errors.New("configuration file already exists")
|
|
}
|
|
|
|
_, ok := err.(viper.ConfigFileNotFoundError)
|
|
if !errors.Is(err, os.ErrNotExist) && !ok {
|
|
// Config file was found but another error was produced
|
|
return err
|
|
}
|
|
|
|
// Load default configuration
|
|
config.LoadDefaultConfig()
|
|
|
|
if viper.ConfigFileUsed() == "" {
|
|
viper.SetConfigFile(config.EtcConfigPath + "/config.yaml")
|
|
}
|
|
|
|
fmt.Print(
|
|
"writing default configuration to file: " +
|
|
viper.ConfigFileUsed() +
|
|
"\n",
|
|
)
|
|
|
|
if err := viper.WriteConfig(); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
},
|
|
}
|
|
// Config flag should be hidden as the config path should be provided
|
|
cmd.SetHelpFunc(func(command *cobra.Command, strings []string) {
|
|
command.Flags().MarkHidden("config") //nolint:errcheck,gosec // a root flag, so it always exists
|
|
command.Parent().HelpFunc()(command, strings)
|
|
})
|
|
return cmd
|
|
}
|