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.
74 lines
1.8 KiB
Go
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, ¬Found) {
|
|
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()
|
|
}
|