diff --git a/mcfg/cli.go b/mcfg/cli.go index fcf2968..4393669 100644 --- a/mcfg/cli.go +++ b/mcfg/cli.go @@ -7,6 +7,8 @@ import ( "reflect" "sort" "strings" + + "github.com/mediocregopher/mediocre-go-lib/merr" ) // SourceCLI is a Source which will parse configuration from the CLI. @@ -86,7 +88,8 @@ func (cli SourceCLI) Parse(params []Param) ([]ParamValue, error) { break } if !pvOk { - return nil, fmt.Errorf("unexpected config parameter %q", arg) + err := merr.New("unexpected config parameter") + return nil, merr.WithValue(err, "param", arg, true) } } @@ -114,7 +117,8 @@ func (cli SourceCLI) Parse(params []Param) ([]ParamValue, error) { pvStrValOk = false } if pvOk && !pvStrValOk { - return nil, fmt.Errorf("param %q expected a value", key) + err := merr.New("param expected a value") + return nil, merr.WithValue(err, "param", key, true) } return pvs, nil } @@ -140,6 +144,9 @@ func (cli SourceCLI) printHelp(w io.Writer, pM map[string]Param) { } sort.Slice(pA, func(i, j int) bool { + if pA[i].Required != pA[j].Required { + return pA[i].Required + } return pA[i].arg < pA[j].arg }) @@ -161,6 +168,8 @@ func (cli SourceCLI) printHelp(w io.Writer, pM map[string]Param) { fmt.Fprintf(w, "\n%s", p.arg) if p.IsBool { fmt.Fprintf(w, " (Flag)") + } else if p.Required { + fmt.Fprintf(w, " (Required)") } else if defVal := fmtDefaultVal(p.Into); defVal != "" { fmt.Fprintf(w, " (Default: %s)", defVal) } diff --git a/mcfg/cli_test.go b/mcfg/cli_test.go index e0f0114..b696687 100644 --- a/mcfg/cli_test.go +++ b/mcfg/cli_test.go @@ -18,7 +18,8 @@ func TestSourceCLIHelp(t *T) { Int(ctx, "foo", 5, "Test int param") Bool(ctx, "bar", "Test bool param") String(ctx, "baz", "baz", "Test string param") - String(ctx, "baz2", "", "") + RequiredString(ctx, "baz2", "") + RequiredString(ctx, "baz3", "") src := SourceCLI{} buf := new(bytes.Buffer) @@ -27,14 +28,16 @@ func TestSourceCLIHelp(t *T) { SourceCLI{}.printHelp(buf, pM) exp := ` +--baz2 (Required) + +--baz3 (Required) + --bar (Flag) Test bool param --baz (Default: "baz") Test string param ---baz2 - --foo (Default: 5) Test int param diff --git a/mcfg/env.go b/mcfg/env.go index dfe4cde..026fa49 100644 --- a/mcfg/env.go +++ b/mcfg/env.go @@ -1,9 +1,10 @@ package mcfg import ( - "fmt" "os" "strings" + + "github.com/mediocregopher/mediocre-go-lib/merr" ) // SourceEnv is a Source which will parse configuration from the process @@ -56,7 +57,8 @@ func (env SourceEnv) Parse(params []Param) ([]ParamValue, error) { for _, kv := range kvs { split := strings.SplitN(kv, "=", 2) if len(split) != 2 { - return nil, fmt.Errorf("malformed environment kv %q", kv) + err := merr.New("malformed environment key/value pair") + return nil, merr.WithValue(err, "kv", kv, true) } k, v := split[0], split[1] if p, ok := pM[k]; ok { diff --git a/mcfg/mcfg.go b/mcfg/mcfg.go index 152e3d3..e63f5da 100644 --- a/mcfg/mcfg.go +++ b/mcfg/mcfg.go @@ -4,10 +4,10 @@ package mcfg import ( "encoding/json" - "fmt" "sort" "github.com/mediocregopher/mediocre-go-lib/mctx" + "github.com/mediocregopher/mediocre-go-lib/merr" ) // TODO Sources: @@ -97,7 +97,8 @@ func populate(params []Param, src Source) error { if !param.Required { continue } else if _, ok := pvM[param.hash()]; !ok { - return fmt.Errorf("param %q is required", param.fullName()) + err := merr.New("required parameter is not set") + return merr.WithValue(err, "param", param.fullName(), true) } } diff --git a/mcfg/source.go b/mcfg/source.go index 152f654..8c8717e 100644 --- a/mcfg/source.go +++ b/mcfg/source.go @@ -44,6 +44,7 @@ func (ss Sources) Parse(params []Param) ([]ParamValue, error) { // variables. type SourceMap map[string]string +// Parse implements the method for the Source interface. func (m SourceMap) Parse(params []Param) ([]ParamValue, error) { pvs := make([]ParamValue, 0, len(m)) for _, p := range params {