func initViper()

in cmd/root.go [701:750]


func initViper(c *Command) (*viper.Viper, error) {
	v := viper.New()

	if c.conf.Filepath != "" {
		// Setup Viper configuration file. Viper will attempt to load
		// configuration from the specified file if it exists. Otherwise, Viper
		// will source all configuration from flags and then environment
		// variables.
		ext := filepath.Ext(c.conf.Filepath)

		badExtErr := newBadCommandError(
			fmt.Sprintf("config file %v should have extension of "+
				"toml, yaml, or json", c.conf.Filepath,
			))

		if ext == "" {
			return nil, badExtErr
		}

		if ext != ".toml" && ext != ".yaml" && ext != ".yml" && ext != ".json" {
			return nil, badExtErr
		}

		conf := filepath.Base(c.conf.Filepath)
		noExt := strings.ReplaceAll(conf, ext, "")
		// argument must be the name of config file without extension
		v.SetConfigName(noExt)
		v.AddConfigPath(filepath.Dir(c.conf.Filepath))

		// Attempt to load configuration from a file. If no file is found,
		// assume configuration is provided by flags or environment variables.
		if err := v.ReadInConfig(); err != nil {
			// If the error is a ConfigFileNotFoundError, then ignore it.
			// Otherwise, report the error to the user.
			var cErr viper.ConfigFileNotFoundError
			if !errors.As(err, &cErr) {
				return nil, newBadCommandError(fmt.Sprintf(
					"failed to load configuration from %v: %v",
					c.conf.Filepath, err,
				))
			}
		}
	}

	v.SetEnvPrefix(envPrefix)
	v.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
	v.AutomaticEnv()

	return v, nil
}