Skip to content

Commit

Permalink
Fixed unmarshalling json input into interface{} type (#1832)
Browse files Browse the repository at this point in the history
## Changes
Fixed unmarshalling json input into `interface{}` type

Commands like `api post` support free form request input, so it should
be unmarshaled correctly

## Tests
Added regression test + E2E test pass
  • Loading branch information
andrewnester authored Oct 15, 2024
1 parent ab20624 commit 0753dfe
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 14 deletions.
24 changes: 19 additions & 5 deletions libs/flags/json_flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"os"
"reflect"

"github.com/databricks/cli/libs/diag"
"github.com/databricks/cli/libs/dyn/convert"
Expand Down Expand Up @@ -63,11 +64,24 @@ func (j *JsonFlag) Unmarshal(v any) diag.Diagnostics {
return diags.Extend(diag.FromErr(err))
}

// Finally unmarshal the normalized data to the output.
// It will fill in the ForceSendFields field if the struct contains it.
err = marshal.Unmarshal(data, v)
if err != nil {
return diags.Extend(diag.FromErr(err))
kind := reflect.ValueOf(v).Kind()
if kind == reflect.Ptr {
kind = reflect.ValueOf(v).Elem().Kind()
}

if kind == reflect.Struct {
// Finally unmarshal the normalized data to the output.
// It will fill in the ForceSendFields field if the struct contains it.
err = marshal.Unmarshal(data, v)
if err != nil {
return diags.Extend(diag.FromErr(err))
}
} else {
// If the output is not a struct, just unmarshal the data to the output.
err = json.Unmarshal(data, v)
if err != nil {
return diags.Extend(diag.FromErr(err))
}
}

return diags
Expand Down
14 changes: 5 additions & 9 deletions libs/flags/json_flag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ import (
"github.com/stretchr/testify/require"
)

type requestType struct {
Foo string `json:"foo"`
}

func TestJsonFlagEmpty(t *testing.T) {
var body JsonFlag

Expand All @@ -35,13 +31,13 @@ func TestJsonFlagInline(t *testing.T) {
err := body.Set(`{"foo": "bar"}`)
assert.NoError(t, err)

var request requestType
var request any
diags := body.Unmarshal(&request)
assert.NoError(t, diags.Error())
assert.Empty(t, diags)

assert.Equal(t, "JSON (14 bytes)", body.String())
assert.Equal(t, requestType{"bar"}, request)
assert.Equal(t, map[string]any{"foo": "bar"}, request)
}

func TestJsonFlagError(t *testing.T) {
Expand All @@ -50,15 +46,15 @@ func TestJsonFlagError(t *testing.T) {
err := body.Set(`{"foo":`)
assert.NoError(t, err)

var request requestType
var request any
diags := body.Unmarshal(&request)
assert.EqualError(t, diags.Error(), "error decoding JSON at (inline):1:8: unexpected end of JSON input")
assert.Equal(t, "JSON (7 bytes)", body.String())
}

func TestJsonFlagFile(t *testing.T) {
var body JsonFlag
var request requestType
var request any

var fpath string
var payload = []byte(`{"foo": "bar"}`)
Expand All @@ -78,7 +74,7 @@ func TestJsonFlagFile(t *testing.T) {
assert.NoError(t, diags.Error())
assert.Empty(t, diags)

assert.Equal(t, requestType{"bar"}, request)
assert.Equal(t, map[string]any{"foo": "bar"}, request)
}

const jsonData = `
Expand Down

0 comments on commit 0753dfe

Please sign in to comment.