4b446a0efc
This change required refactoring nearly every package in this project, but it does a lot to simplify mctx and make other code using it easier to think about. Other code, such as mlog and mcfg, had to be slightly modified for this change to work as well.
75 lines
1.9 KiB
Go
75 lines
1.9 KiB
Go
package mcfg
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/mediocregopher/mediocre-go-lib/mctx"
|
|
"github.com/mediocregopher/mediocre-go-lib/merr"
|
|
)
|
|
|
|
// SourceEnv is a Source which will parse configuration from the process
|
|
// environment.
|
|
//
|
|
// Possible Env options are generated by joining a Param's Path and Name with
|
|
// underscores and making all characters uppercase, as well as changing all
|
|
// dashes to underscores.
|
|
//
|
|
// ctx := mctx.New()
|
|
// ctx = mctx.ChildOf(ctx, "foo")
|
|
// ctx = mctx.ChildOf(ctx, "bar")
|
|
// addr := mcfg.String(ctx, "srv-addr", "", "Some address")
|
|
// // the Env option to fill addr will be "FOO_BAR_SRV_ADDR"
|
|
//
|
|
type SourceEnv struct {
|
|
// In the format key=value. Defaults to os.Environ() if nil.
|
|
Env []string
|
|
|
|
// If set then all expected Env options must be prefixed with this string,
|
|
// which will be uppercased and have dashes replaced with underscores like
|
|
// all the other parts of the option names.
|
|
Prefix string
|
|
}
|
|
|
|
func (env SourceEnv) expectedName(path []string, name string) string {
|
|
out := strings.Join(append(path, name), "_")
|
|
if env.Prefix != "" {
|
|
out = env.Prefix + "_" + out
|
|
}
|
|
out = strings.Replace(out, "-", "_", -1)
|
|
out = strings.ToUpper(out)
|
|
return out
|
|
}
|
|
|
|
// Parse implements the method for the Source interface
|
|
func (env SourceEnv) Parse(params []Param) ([]ParamValue, error) {
|
|
kvs := env.Env
|
|
if kvs == nil {
|
|
kvs = os.Environ()
|
|
}
|
|
|
|
pM := map[string]Param{}
|
|
for _, p := range params {
|
|
name := env.expectedName(mctx.Path(p.Context), p.Name)
|
|
pM[name] = p
|
|
}
|
|
|
|
pvs := make([]ParamValue, 0, len(kvs))
|
|
for _, kv := range kvs {
|
|
split := strings.SplitN(kv, "=", 2)
|
|
if len(split) != 2 {
|
|
return nil, merr.New("malformed environment key/value pair", "kv", kv)
|
|
}
|
|
k, v := split[0], split[1]
|
|
if p, ok := pM[k]; ok {
|
|
pvs = append(pvs, ParamValue{
|
|
Name: p.Name,
|
|
Path: mctx.Path(p.Context),
|
|
Value: p.fuzzyParse(v),
|
|
})
|
|
}
|
|
}
|
|
|
|
return pvs, nil
|
|
}
|