diff --git a/mcfg/cli.go b/mcfg/cli.go index c6a3047..8aca3c2 100644 --- a/mcfg/cli.go +++ b/mcfg/cli.go @@ -122,31 +122,14 @@ func (cli SourceCLI) Parse(cfg *Cfg) ([]ParamValue, error) { func (cli SourceCLI) cliParamVals(cfg *Cfg) (map[string]ParamValue, error) { m := map[string]ParamValue{} - for _, param := range cfg.Params { + for _, pv := range cfg.allParamValues() { key := cliKeyPrefix - if !cfg.IsRoot() { - key += strings.Join(cfg.Path, cliKeyJoin) + cliKeyJoin - } - key += param.Name - m[key] = ParamValue{ - Param: param, - Path: cfg.Path, + if len(pv.Path) > 0 { + key += strings.Join(pv.Path, cliKeyJoin) + cliKeyJoin } + key += pv.Param.Name + m[key] = pv } - - for _, child := range cfg.Children { - childM, err := cli.cliParamVals(child) - if err != nil { - return nil, err - } - for key, pv := range childM { - if _, ok := m[key]; ok { - return nil, fmt.Errorf("multiple params use the same CLI arg %q", key) - } - m[key] = pv - } - } - return m, nil } diff --git a/mcfg/mcfg.go b/mcfg/mcfg.go index 2507371..0d70100 100644 --- a/mcfg/mcfg.go +++ b/mcfg/mcfg.go @@ -62,19 +62,6 @@ func (h *Hook) Also(h2 Hook) { } } -// ParamValue describes a value for a parameter which has been parsed by a -// Source -type ParamValue struct { - Param - Path []string // nil if root - Value json.RawMessage -} - -// Source parses ParamValues out of a particular configuration source -type Source interface { - Parse(*Cfg) ([]ParamValue, error) -} - // Cfg describes a set of configuration parameters and run-time behaviors. // Parameters are defined using the Param* methods, and run-time behaviors by // the Hook fields on this struct. diff --git a/mcfg/source.go b/mcfg/source.go new file mode 100644 index 0000000..185d9c9 --- /dev/null +++ b/mcfg/source.go @@ -0,0 +1,32 @@ +package mcfg + +import "encoding/json" + +// ParamValue describes a value for a parameter which has been parsed by a +// Source +type ParamValue struct { + Param + Path []string // nil if root + Value json.RawMessage +} + +func (cfg *Cfg) allParamValues() []ParamValue { + pvs := make([]ParamValue, 0, len(cfg.Params)) + for _, param := range cfg.Params { + pvs = append(pvs, ParamValue{ + Param: param, + Path: cfg.Path, + }) + } + + for _, child := range cfg.Children { + pvs = append(pvs, child.allParamValues()...) + } + return pvs +} + +// Source parses ParamValues out of a particular configuration source. The +// returned []ParamValue may contain duplicates of the same Param's value. +type Source interface { + Parse(*Cfg) ([]ParamValue, error) +}