diff --git a/resolver.go b/resolver.go index 2fa626f..ac1de1f 100644 --- a/resolver.go +++ b/resolver.go @@ -29,7 +29,7 @@ func (r ResolverFunc) Validate(app *Application) error { return nil } // nolint: // JSON returns a Resolver that retrieves values from a JSON source. // -// Hyphens in flag names are replaced with underscores. +// Flag names are used as JSON keys indirectly, by tring snake_case and camelCase variants. func JSON(r io.Reader) (Resolver, error) { values := map[string]interface{}{} err := json.NewDecoder(r).Decode(&values) @@ -38,9 +38,12 @@ func JSON(r io.Reader) (Resolver, error) { } var f ResolverFunc = func(context *Context, parent *Path, flag *Flag) (interface{}, error) { name := strings.ReplaceAll(flag.Name, "-", "_") + snakeCaseName := snakeCase(flag.Name) raw, ok := values[name] if ok { return raw, nil + } else if raw, ok = values[snakeCaseName]; ok { + return raw, nil } raw = values for _, part := range strings.Split(name, ".") { @@ -58,3 +61,8 @@ func JSON(r io.Reader) (Resolver, error) { return f, nil } + +func snakeCase(name string) string { + name = strings.Join(strings.Split(strings.Title(name), "-"), "") //nolint: staticcheck + return strings.ToLower(name[:1]) + name[1:] +} diff --git a/resolver_test.go b/resolver_test.go index bb3e2c6..3c4ded0 100644 --- a/resolver_test.go +++ b/resolver_test.go @@ -206,7 +206,7 @@ func TestJSONBasic(t *testing.T) { "string": "🍕", "slice": [5, 8], "bool": true, - "slice_with_commas": ["a,b", "c"], + "sliceWithCommas": ["a,b", "c"], "one":{ "string": "one value" },