mcfg: use merr for returned errors, and make help output prioritize required params towards the top

This commit is contained in:
Brian Picciano 2019-01-24 22:02:04 -05:00
parent ef2e76de45
commit 05a69589bc
5 changed files with 25 additions and 9 deletions

View File

@ -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)
}

View File

@ -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

View File

@ -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 {

View File

@ -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)
}
}

View File

@ -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 {