mcfg: simplify populateParams
This commit is contained in:
parent
2e9790451f
commit
be17ee942a
@ -123,12 +123,8 @@ func (cli SourceCLI) Parse(cfg *Cfg) ([]ParamValue, error) {
|
|||||||
func (cli SourceCLI) cliParamVals(cfg *Cfg) (map[string]ParamValue, error) {
|
func (cli SourceCLI) cliParamVals(cfg *Cfg) (map[string]ParamValue, error) {
|
||||||
m := map[string]ParamValue{}
|
m := map[string]ParamValue{}
|
||||||
for _, pv := range cfg.allParamValues() {
|
for _, pv := range cfg.allParamValues() {
|
||||||
key := cliKeyPrefix
|
key := strings.Join(append(pv.Path, pv.Param.Name), cliKeyJoin)
|
||||||
if len(pv.Path) > 0 {
|
m[cliKeyPrefix+key] = pv
|
||||||
key += strings.Join(pv.Path, cliKeyJoin) + cliKeyJoin
|
|
||||||
}
|
|
||||||
key += pv.Param.Name
|
|
||||||
m[key] = pv
|
|
||||||
}
|
}
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
55
mcfg/mcfg.go
55
mcfg/mcfg.go
@ -140,62 +140,23 @@ func (c *Cfg) populateParams(src Source) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// first dedupe the params. We use this param struct as the key by which to
|
// dedupe the ParamValues based on their hashes, with the last ParamValue
|
||||||
// dedupe by. Its use depends on the json.Marshaler always ordering fields
|
// taking precedence
|
||||||
// in a marshaled struct the same way, which isn't the best assumption but
|
|
||||||
// it's ok for now
|
|
||||||
type param struct {
|
|
||||||
Path []string `json:",omitempty"`
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
paramFullName := func(p param) string {
|
|
||||||
if len(p.Path) == 0 {
|
|
||||||
return p.Name
|
|
||||||
}
|
|
||||||
slice := append(make([]string, 0, len(p.Path)+1), p.Name)
|
|
||||||
slice = append(slice, p.Path...)
|
|
||||||
return strings.Join(slice, "-")
|
|
||||||
}
|
|
||||||
|
|
||||||
pvM := map[string]ParamValue{}
|
pvM := map[string]ParamValue{}
|
||||||
for _, pv := range pvs {
|
for _, pv := range pvs {
|
||||||
keyB, err := json.Marshal(param{Path: pv.Path, Name: pv.Name})
|
pvM[pv.hash()] = pv
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
pvM[string(keyB)] = pv
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for required params, again using the param struct and the existing
|
// check for required params
|
||||||
// pvM
|
for _, pv := range c.allParamValues() {
|
||||||
var requiredParams func(*Cfg) []param
|
if !pv.Param.Required {
|
||||||
requiredParams = func(c *Cfg) []param {
|
|
||||||
var out []param
|
|
||||||
for _, p := range c.Params {
|
|
||||||
if !p.Required {
|
|
||||||
continue
|
continue
|
||||||
}
|
} else if _, ok := pvM[pv.hash()]; !ok {
|
||||||
out = append(out, param{Path: c.Path, Name: p.Name})
|
return fmt.Errorf("param %q is required", pv.displayName())
|
||||||
}
|
|
||||||
for _, child := range c.Children {
|
|
||||||
out = append(out, requiredParams(child)...)
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, reqP := range requiredParams(c) {
|
|
||||||
keyB, err := json.Marshal(reqP)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
} else if _, ok := pvM[string(keyB)]; !ok {
|
|
||||||
return fmt.Errorf("param %s is required but wasn't populated by any configuration source", paramFullName(reqP))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, pv := range pvM {
|
for _, pv := range pvM {
|
||||||
if pv.Into == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := json.Unmarshal(pv.Value, pv.Into); err != nil {
|
if err := json.Unmarshal(pv.Value, pv.Into); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
package mcfg
|
package mcfg
|
||||||
|
|
||||||
import "encoding/json"
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
// ParamValue describes a value for a parameter which has been parsed by a
|
// ParamValue describes a value for a parameter which has been parsed by a
|
||||||
// Source
|
// Source
|
||||||
@ -10,6 +16,21 @@ type ParamValue struct {
|
|||||||
Value json.RawMessage
|
Value json.RawMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pv ParamValue) displayName() string {
|
||||||
|
return strings.Join(append(pv.Path, pv.Param.Name), "-")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pv ParamValue) hash() string {
|
||||||
|
h := md5.New()
|
||||||
|
for _, path := range pv.Path {
|
||||||
|
fmt.Fprintf(h, "pathEl:%q\n", path)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(h, "name:%q\n", pv.Param.Name)
|
||||||
|
hStr := hex.EncodeToString(h.Sum(nil))
|
||||||
|
// we add the displayName to it to make debugging easier
|
||||||
|
return pv.displayName() + "/" + hStr
|
||||||
|
}
|
||||||
|
|
||||||
func (cfg *Cfg) allParamValues() []ParamValue {
|
func (cfg *Cfg) allParamValues() []ParamValue {
|
||||||
pvs := make([]ParamValue, 0, len(cfg.Params))
|
pvs := make([]ParamValue, 0, len(cfg.Params))
|
||||||
for _, param := range cfg.Params {
|
for _, param := range cfg.Params {
|
||||||
|
Loading…
Reference in New Issue
Block a user