Files
x/internal/cli/config.go
T
sneak 4d45aa4ca3 Restore config loading, keep exported Version, keep cgo off
Bring back the in-progress viper and go-homedir configuration loading
from the original root command as a persistent pre-run on the root
command, with a --config flag and a config line in sutil info. Restore
the exported main.Version with a nolint directive instead of renaming
it. Export CGO_ENABLED=0 from the Makefile, drop -race from make test,
and remove the C toolchain from the Docker builder stage.
2026-10-31 10:11:47 -07:00

74 lines
1.8 KiB
Go

package cli
import (
"errors"
"fmt"
"github.com/mitchellh/go-homedir"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
// configName is the base name of the optional configuration file looked
// up in the config directory; viper tries every extension it supports, so
// ~/.sneak.yaml, ~/.sneak.json, ~/.sneak.toml, and so on all work.
const configName = ".sneak"
// loadConfig runs before every command. It reads the optional
// configuration file into a.config and makes environment variables
// available through it. The file is the one named by --config, or else
// configName in Params.ConfigDir, which defaults to the user's home
// directory. A missing default file is not an error; a file that is named
// explicitly but missing, or one that cannot be parsed, is.
func (a *app) loadConfig(cmd *cobra.Command, _ []string) error {
configDir := a.params.ConfigDir
if configDir == "" {
home, err := homedir.Dir()
if err != nil {
return fmt.Errorf("finding home directory: %w", err)
}
configDir = home
}
config := viper.New()
config.AddConfigPath(configDir)
config.SetConfigName(configName)
config.AutomaticEnv()
if a.configFile != "" {
config.SetConfigFile(a.configFile)
}
err := config.ReadInConfig()
var notFound viper.ConfigFileNotFoundError
if errors.As(err, &notFound) {
a.config = config
return nil
}
if err != nil {
return fmt.Errorf("reading config file: %w", err)
}
a.config = config
_, err = fmt.Fprintln(
cmd.ErrOrStderr(), "Using config file:", config.ConfigFileUsed(),
)
return err
}
// configFileUsed returns the path of the configuration file that
// loadConfig read, or an empty string if there was none.
func (a *app) configFileUsed() string {
if a.config == nil {
return ""
}
return a.config.ConfigFileUsed()
}