piframe-go/vendor/github.com/knadh/koanf/providers/posflag/posflag.go

101 lines
2.7 KiB
Go

// Package posflag implements a koanf.Provider that reads commandline
// parameters as conf maps using spf13/pflag, a POSIX compliant
// alternative to Go's stdlib flag package.
package posflag
import (
"errors"
"github.com/knadh/koanf"
"github.com/knadh/koanf/maps"
"github.com/spf13/pflag"
)
// Posflag implements a pflag command line provider.
type Posflag struct {
delim string
flagset *pflag.FlagSet
ko *koanf.Koanf
}
// Provider returns a commandline flags provider that returns
// a nested map[string]interface{} of environment variable where the
// nesting hierarchy of keys are defined by delim. For instance, the
// delim "." will convert the key `parent.child.key: 1`
// to `{parent: {child: {key: 1}}}`.
//
// It takes an optional (but recommended) Koanf instance to see if the
// the flags defined have been set from other providers, for instance,
// a config file. If they are not, then the default values of the flags
// are merged. If they do exist, the flag values are not merged but only
// the values that have been explicitly set in the command line are merged.
func Provider(f *pflag.FlagSet, delim string, ko *koanf.Koanf) *Posflag {
return &Posflag{
flagset: f,
delim: delim,
ko: ko,
}
}
// Read reads the flag variables and returns a nested conf map.
func (p *Posflag) Read() (map[string]interface{}, error) {
mp := make(map[string]interface{})
p.flagset.VisitAll(func(f *pflag.Flag) {
// If no value was explicitly set in the command line,
// check if the default value should be used.
if !f.Changed {
if p.ko != nil {
if p.ko.Exists(f.Name) {
return
}
} else {
return
}
}
var v interface{}
switch f.Value.Type() {
case "int":
i, _ := p.flagset.GetInt(f.Name)
v = int64(i)
case "int8":
i, _ := p.flagset.GetInt8(f.Name)
v = int64(i)
case "int16":
i, _ := p.flagset.GetInt16(f.Name)
v = int64(i)
case "int32":
i, _ := p.flagset.GetInt32(f.Name)
v = int64(i)
case "int64":
i, _ := p.flagset.GetInt64(f.Name)
v = int64(i)
case "float32":
v, _ = p.flagset.GetFloat32(f.Name)
case "float":
v, _ = p.flagset.GetFloat64(f.Name)
case "bool":
v, _ = p.flagset.GetBool(f.Name)
case "stringSlice":
v, _ = p.flagset.GetStringSlice(f.Name)
case "intSlice":
v, _ = p.flagset.GetIntSlice(f.Name)
default:
v = f.Value.String()
}
mp[f.Name] = v
})
return maps.Unflatten(mp, p.delim), nil
}
// ReadBytes is not supported by the env koanf.
func (p *Posflag) ReadBytes() ([]byte, error) {
return nil, errors.New("pflag provider does not support this method")
}
// Watch is not supported.
func (p *Posflag) Watch(cb func(event interface{}, err error)) error {
return errors.New("posflag provider does not support this method")
}