diff --git a/libs/config/path_test.go b/libs/config/path_test.go deleted file mode 100644 index 3fdd848e..00000000 --- a/libs/config/path_test.go +++ /dev/null @@ -1,76 +0,0 @@ -package config_test - -import ( - "testing" - - "github.com/databricks/cli/libs/config" - "github.com/stretchr/testify/assert" -) - -func TestPathAppend(t *testing.T) { - p := config.NewPath(config.Key("foo")) - - // Single arg. - p1 := p.Append(config.Key("bar")) - assert.True(t, p1.Equal(config.NewPath(config.Key("foo"), config.Key("bar")))) - - // Multiple args. - p2 := p.Append(config.Key("bar"), config.Index(1)) - assert.True(t, p2.Equal(config.NewPath(config.Key("foo"), config.Key("bar"), config.Index(1)))) -} - -func TestPathJoin(t *testing.T) { - p := config.NewPath(config.Key("foo")) - - // Single arg. - p1 := p.Join(config.NewPath(config.Key("bar"))) - assert.True(t, p1.Equal(config.NewPath(config.Key("foo"), config.Key("bar")))) - - // Multiple args. - p2 := p.Join(config.NewPath(config.Key("bar")), config.NewPath(config.Index(1))) - assert.True(t, p2.Equal(config.NewPath(config.Key("foo"), config.Key("bar"), config.Index(1)))) -} - -func TestPathEqualEmpty(t *testing.T) { - assert.True(t, config.EmptyPath.Equal(config.EmptyPath)) -} - -func TestPathEqual(t *testing.T) { - p1 := config.NewPath(config.Key("foo"), config.Index(1)) - p2 := config.NewPath(config.Key("bar"), config.Index(2)) - assert.False(t, p1.Equal(p2), "expected %q to not equal %q", p1, p2) - - p3 := config.NewPath(config.Key("foo"), config.Index(1)) - assert.True(t, p1.Equal(p3), "expected %q to equal %q", p1, p3) - - p4 := config.NewPath(config.Key("foo"), config.Index(1), config.Key("bar"), config.Index(2)) - assert.False(t, p1.Equal(p4), "expected %q to not equal %q", p1, p4) -} - -func TestPathHasPrefixEmpty(t *testing.T) { - empty := config.EmptyPath - nonEmpty := config.NewPath(config.Key("foo")) - assert.True(t, empty.HasPrefix(empty)) - assert.True(t, nonEmpty.HasPrefix(empty)) - assert.False(t, empty.HasPrefix(nonEmpty)) -} - -func TestPathHasPrefix(t *testing.T) { - p1 := config.NewPath(config.Key("foo"), config.Index(1)) - p2 := config.NewPath(config.Key("bar"), config.Index(2)) - assert.False(t, p1.HasPrefix(p2), "expected %q to not have prefix %q", p1, p2) - - p3 := config.NewPath(config.Key("foo")) - assert.True(t, p1.HasPrefix(p3), "expected %q to have prefix %q", p1, p3) -} - -func TestPathString(t *testing.T) { - p1 := config.NewPath(config.Key("foo"), config.Index(1)) - assert.Equal(t, "foo[1]", p1.String()) - - p2 := config.NewPath(config.Key("bar"), config.Index(2), config.Key("baz")) - assert.Equal(t, "bar[2].baz", p2.String()) - - p3 := config.NewPath(config.Key("foo"), config.Index(1), config.Key("bar"), config.Index(2), config.Key("baz")) - assert.Equal(t, "foo[1].bar[2].baz", p3.String()) -} diff --git a/libs/diag/diagnostic.go b/libs/diag/diagnostic.go index c5757a58..02d2e7c1 100644 --- a/libs/diag/diagnostic.go +++ b/libs/diag/diagnostic.go @@ -3,7 +3,7 @@ package diag import ( "fmt" - "github.com/databricks/cli/libs/config" + "github.com/databricks/cli/libs/dyn" ) type Diagnostic struct { @@ -19,7 +19,7 @@ type Diagnostic struct { // Location is a source code location associated with the diagnostic message. // It may be zero if there is no associated location. - Location config.Location + Location dyn.Location } // Errorf creates a new error diagnostic. diff --git a/libs/config/convert/end_to_end_test.go b/libs/dyn/convert/end_to_end_test.go similarity index 93% rename from libs/config/convert/end_to_end_test.go rename to libs/dyn/convert/end_to_end_test.go index c06830e8..fbb84336 100644 --- a/libs/config/convert/end_to_end_test.go +++ b/libs/dyn/convert/end_to_end_test.go @@ -3,13 +3,13 @@ package convert import ( "testing" - "github.com/databricks/cli/libs/config" + "github.com/databricks/cli/libs/dyn" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func assertFromTypedToTypedEqual[T any](t *testing.T, src T) { - nv, err := FromTyped(src, config.NilValue) + nv, err := FromTyped(src, dyn.NilValue) require.NoError(t, err) var dst T diff --git a/libs/config/convert/error.go b/libs/dyn/convert/error.go similarity index 73% rename from libs/config/convert/error.go rename to libs/dyn/convert/error.go index b55668d6..d3770d82 100644 --- a/libs/config/convert/error.go +++ b/libs/dyn/convert/error.go @@ -3,11 +3,11 @@ package convert import ( "fmt" - "github.com/databricks/cli/libs/config" + "github.com/databricks/cli/libs/dyn" ) type TypeError struct { - value config.Value + value dyn.Value msg string } diff --git a/libs/config/convert/from_typed.go b/libs/dyn/convert/from_typed.go similarity index 58% rename from libs/config/convert/from_typed.go rename to libs/dyn/convert/from_typed.go index e3911a9e..0659d1cd 100644 --- a/libs/config/convert/from_typed.go +++ b/libs/dyn/convert/from_typed.go @@ -4,18 +4,18 @@ import ( "fmt" "reflect" - "github.com/databricks/cli/libs/config" + "github.com/databricks/cli/libs/dyn" ) // FromTyped converts changes made in the typed structure w.r.t. the configuration value // back to the configuration value, retaining existing location information where possible. -func FromTyped(src any, ref config.Value) (config.Value, error) { +func FromTyped(src any, ref dyn.Value) (dyn.Value, error) { srcv := reflect.ValueOf(src) // Dereference pointer if necessary for srcv.Kind() == reflect.Pointer { if srcv.IsNil() { - return config.NilValue, nil + return dyn.NilValue, nil } srcv = srcv.Elem() } @@ -37,53 +37,53 @@ func FromTyped(src any, ref config.Value) (config.Value, error) { return fromTypedFloat(srcv, ref) } - return config.NilValue, fmt.Errorf("unsupported type: %s", srcv.Kind()) + return dyn.NilValue, fmt.Errorf("unsupported type: %s", srcv.Kind()) } -func fromTypedStruct(src reflect.Value, ref config.Value) (config.Value, error) { +func fromTypedStruct(src reflect.Value, ref dyn.Value) (dyn.Value, error) { // Check that the reference value is compatible or nil. switch ref.Kind() { - case config.KindMap, config.KindNil: + case dyn.KindMap, dyn.KindNil: default: - return config.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind()) + return dyn.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind()) } - out := make(map[string]config.Value) + out := make(map[string]dyn.Value) info := getStructInfo(src.Type()) for k, v := range info.FieldValues(src) { // Convert the field taking into account the reference value (may be equal to config.NilValue). nv, err := FromTyped(v.Interface(), ref.Get(k)) if err != nil { - return config.Value{}, err + return dyn.Value{}, err } - if nv != config.NilValue { + if nv != dyn.NilValue { out[k] = nv } } // If the struct was equal to its zero value, emit a nil. if len(out) == 0 { - return config.NilValue, nil + return dyn.NilValue, nil } - return config.NewValue(out, ref.Location()), nil + return dyn.NewValue(out, ref.Location()), nil } -func fromTypedMap(src reflect.Value, ref config.Value) (config.Value, error) { +func fromTypedMap(src reflect.Value, ref dyn.Value) (dyn.Value, error) { // Check that the reference value is compatible or nil. switch ref.Kind() { - case config.KindMap, config.KindNil: + case dyn.KindMap, dyn.KindNil: default: - return config.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind()) + return dyn.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind()) } // Return nil if the map is nil. if src.IsNil() { - return config.NilValue, nil + return dyn.NilValue, nil } - out := make(map[string]config.Value) + out := make(map[string]dyn.Value) iter := src.MapRange() for iter.Next() { k := iter.Key().String() @@ -92,7 +92,7 @@ func fromTypedMap(src reflect.Value, ref config.Value) (config.Value, error) { // Convert entry taking into account the reference value (may be equal to config.NilValue). nv, err := FromTyped(v.Interface(), ref.Get(k)) if err != nil { - return config.Value{}, err + return dyn.Value{}, err } // Every entry is represented, even if it is a nil. @@ -100,115 +100,115 @@ func fromTypedMap(src reflect.Value, ref config.Value) (config.Value, error) { out[k] = nv } - return config.NewValue(out, ref.Location()), nil + return dyn.NewValue(out, ref.Location()), nil } -func fromTypedSlice(src reflect.Value, ref config.Value) (config.Value, error) { +func fromTypedSlice(src reflect.Value, ref dyn.Value) (dyn.Value, error) { // Check that the reference value is compatible or nil. switch ref.Kind() { - case config.KindSequence, config.KindNil: + case dyn.KindSequence, dyn.KindNil: default: - return config.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind()) + return dyn.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind()) } // Return nil if the slice is nil. if src.IsNil() { - return config.NilValue, nil + return dyn.NilValue, nil } - out := make([]config.Value, src.Len()) + out := make([]dyn.Value, src.Len()) for i := 0; i < src.Len(); i++ { v := src.Index(i) // Convert entry taking into account the reference value (may be equal to config.NilValue). nv, err := FromTyped(v.Interface(), ref.Index(i)) if err != nil { - return config.Value{}, err + return dyn.Value{}, err } out[i] = nv } - return config.NewValue(out, ref.Location()), nil + return dyn.NewValue(out, ref.Location()), nil } -func fromTypedString(src reflect.Value, ref config.Value) (config.Value, error) { +func fromTypedString(src reflect.Value, ref dyn.Value) (dyn.Value, error) { switch ref.Kind() { - case config.KindString: + case dyn.KindString: value := src.String() if value == ref.MustString() { return ref, nil } - return config.V(value), nil - case config.KindNil: + return dyn.V(value), nil + case dyn.KindNil: // This field is not set in the reference, so we only include it if it has a non-zero value. // Otherwise, we would always include all zero valued fields. if src.IsZero() { - return config.NilValue, nil + return dyn.NilValue, nil } - return config.V(src.String()), nil + return dyn.V(src.String()), nil } - return config.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind()) + return dyn.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind()) } -func fromTypedBool(src reflect.Value, ref config.Value) (config.Value, error) { +func fromTypedBool(src reflect.Value, ref dyn.Value) (dyn.Value, error) { switch ref.Kind() { - case config.KindBool: + case dyn.KindBool: value := src.Bool() if value == ref.MustBool() { return ref, nil } - return config.V(value), nil - case config.KindNil: + return dyn.V(value), nil + case dyn.KindNil: // This field is not set in the reference, so we only include it if it has a non-zero value. // Otherwise, we would always include all zero valued fields. if src.IsZero() { - return config.NilValue, nil + return dyn.NilValue, nil } - return config.V(src.Bool()), nil + return dyn.V(src.Bool()), nil } - return config.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind()) + return dyn.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind()) } -func fromTypedInt(src reflect.Value, ref config.Value) (config.Value, error) { +func fromTypedInt(src reflect.Value, ref dyn.Value) (dyn.Value, error) { switch ref.Kind() { - case config.KindInt: + case dyn.KindInt: value := src.Int() if value == ref.MustInt() { return ref, nil } - return config.V(value), nil - case config.KindNil: + return dyn.V(value), nil + case dyn.KindNil: // This field is not set in the reference, so we only include it if it has a non-zero value. // Otherwise, we would always include all zero valued fields. if src.IsZero() { - return config.NilValue, nil + return dyn.NilValue, nil } - return config.V(src.Int()), nil + return dyn.V(src.Int()), nil } - return config.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind()) + return dyn.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind()) } -func fromTypedFloat(src reflect.Value, ref config.Value) (config.Value, error) { +func fromTypedFloat(src reflect.Value, ref dyn.Value) (dyn.Value, error) { switch ref.Kind() { - case config.KindFloat: + case dyn.KindFloat: value := src.Float() if value == ref.MustFloat() { return ref, nil } - return config.V(value), nil - case config.KindNil: + return dyn.V(value), nil + case dyn.KindNil: // This field is not set in the reference, so we only include it if it has a non-zero value. // Otherwise, we would always include all zero valued fields. if src.IsZero() { - return config.NilValue, nil + return dyn.NilValue, nil } - return config.V(src.Float()), nil + return dyn.V(src.Float()), nil } - return config.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind()) + return dyn.Value{}, fmt.Errorf("unhandled type: %s", ref.Kind()) } diff --git a/libs/config/convert/from_typed_test.go b/libs/dyn/convert/from_typed_test.go similarity index 60% rename from libs/config/convert/from_typed_test.go rename to libs/dyn/convert/from_typed_test.go index 2b28f549..0e9b9c7c 100644 --- a/libs/config/convert/from_typed_test.go +++ b/libs/dyn/convert/from_typed_test.go @@ -3,7 +3,7 @@ package convert import ( "testing" - "github.com/databricks/cli/libs/config" + "github.com/databricks/cli/libs/dyn" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -15,11 +15,11 @@ func TestFromTypedStructZeroFields(t *testing.T) { } src := Tmp{} - ref := config.NilValue + ref := dyn.NilValue nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.NilValue, nv) + assert.Equal(t, dyn.NilValue, nv) } func TestFromTypedStructSetFields(t *testing.T) { @@ -33,12 +33,12 @@ func TestFromTypedStructSetFields(t *testing.T) { Bar: "bar", } - ref := config.NilValue + ref := dyn.NilValue nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.V(map[string]config.Value{ - "foo": config.V("foo"), - "bar": config.V("bar"), + assert.Equal(t, dyn.V(map[string]dyn.Value{ + "foo": dyn.V("foo"), + "bar": dyn.V("bar"), }), nv) } @@ -53,45 +53,45 @@ func TestFromTypedStructSetFieldsRetainLocationIfUnchanged(t *testing.T) { Bar: "qux", } - ref := config.V(map[string]config.Value{ - "foo": config.NewValue("bar", config.Location{File: "foo"}), - "bar": config.NewValue("baz", config.Location{File: "bar"}), + ref := dyn.V(map[string]dyn.Value{ + "foo": dyn.NewValue("bar", dyn.Location{File: "foo"}), + "bar": dyn.NewValue("baz", dyn.Location{File: "bar"}), }) nv, err := FromTyped(src, ref) require.NoError(t, err) // Assert foo has retained its location. - assert.Equal(t, config.NewValue("bar", config.Location{File: "foo"}), nv.Get("foo")) + assert.Equal(t, dyn.NewValue("bar", dyn.Location{File: "foo"}), nv.Get("foo")) // Assert bar lost its location (because it was overwritten). - assert.Equal(t, config.NewValue("qux", config.Location{}), nv.Get("bar")) + assert.Equal(t, dyn.NewValue("qux", dyn.Location{}), nv.Get("bar")) } func TestFromTypedMapNil(t *testing.T) { var src map[string]string = nil - ref := config.V(map[string]config.Value{ - "foo": config.V("bar"), - "bar": config.V("baz"), + ref := dyn.V(map[string]dyn.Value{ + "foo": dyn.V("bar"), + "bar": dyn.V("baz"), }) nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.NilValue, nv) + assert.Equal(t, dyn.NilValue, nv) } func TestFromTypedMapEmpty(t *testing.T) { var src = map[string]string{} - ref := config.V(map[string]config.Value{ - "foo": config.V("bar"), - "bar": config.V("baz"), + ref := dyn.V(map[string]dyn.Value{ + "foo": dyn.V("bar"), + "bar": dyn.V("baz"), }) nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.V(map[string]config.Value{}), nv) + assert.Equal(t, dyn.V(map[string]dyn.Value{}), nv) } func TestFromTypedMapNonEmpty(t *testing.T) { @@ -100,12 +100,12 @@ func TestFromTypedMapNonEmpty(t *testing.T) { "bar": "bar", } - ref := config.NilValue + ref := dyn.NilValue nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.V(map[string]config.Value{ - "foo": config.V("foo"), - "bar": config.V("bar"), + assert.Equal(t, dyn.V(map[string]dyn.Value{ + "foo": dyn.V("foo"), + "bar": dyn.V("bar"), }), nv) } @@ -115,19 +115,19 @@ func TestFromTypedMapNonEmptyRetainLocationIfUnchanged(t *testing.T) { "bar": "qux", } - ref := config.V(map[string]config.Value{ - "foo": config.NewValue("bar", config.Location{File: "foo"}), - "bar": config.NewValue("baz", config.Location{File: "bar"}), + ref := dyn.V(map[string]dyn.Value{ + "foo": dyn.NewValue("bar", dyn.Location{File: "foo"}), + "bar": dyn.NewValue("baz", dyn.Location{File: "bar"}), }) nv, err := FromTyped(src, ref) require.NoError(t, err) // Assert foo has retained its location. - assert.Equal(t, config.NewValue("bar", config.Location{File: "foo"}), nv.Get("foo")) + assert.Equal(t, dyn.NewValue("bar", dyn.Location{File: "foo"}), nv.Get("foo")) // Assert bar lost its location (because it was overwritten). - assert.Equal(t, config.NewValue("qux", config.Location{}), nv.Get("bar")) + assert.Equal(t, dyn.NewValue("qux", dyn.Location{}), nv.Get("bar")) } func TestFromTypedMapFieldWithZeroValue(t *testing.T) { @@ -135,38 +135,38 @@ func TestFromTypedMapFieldWithZeroValue(t *testing.T) { "foo": "", } - ref := config.NilValue + ref := dyn.NilValue nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.V(map[string]config.Value{ - "foo": config.NilValue, + assert.Equal(t, dyn.V(map[string]dyn.Value{ + "foo": dyn.NilValue, }), nv) } func TestFromTypedSliceNil(t *testing.T) { var src []string = nil - ref := config.V([]config.Value{ - config.V("bar"), - config.V("baz"), + ref := dyn.V([]dyn.Value{ + dyn.V("bar"), + dyn.V("baz"), }) nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.NilValue, nv) + assert.Equal(t, dyn.NilValue, nv) } func TestFromTypedSliceEmpty(t *testing.T) { var src = []string{} - ref := config.V([]config.Value{ - config.V("bar"), - config.V("baz"), + ref := dyn.V([]dyn.Value{ + dyn.V("bar"), + dyn.V("baz"), }) nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.V([]config.Value{}), nv) + assert.Equal(t, dyn.V([]dyn.Value{}), nv) } func TestFromTypedSliceNonEmpty(t *testing.T) { @@ -175,12 +175,12 @@ func TestFromTypedSliceNonEmpty(t *testing.T) { "bar", } - ref := config.NilValue + ref := dyn.NilValue nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.V([]config.Value{ - config.V("foo"), - config.V("bar"), + assert.Equal(t, dyn.V([]dyn.Value{ + dyn.V("foo"), + dyn.V("bar"), }), nv) } @@ -190,205 +190,205 @@ func TestFromTypedSliceNonEmptyRetainLocationIfUnchanged(t *testing.T) { "bar", } - ref := config.V([]config.Value{ - config.NewValue("foo", config.Location{File: "foo"}), - config.NewValue("baz", config.Location{File: "baz"}), + ref := dyn.V([]dyn.Value{ + dyn.NewValue("foo", dyn.Location{File: "foo"}), + dyn.NewValue("baz", dyn.Location{File: "baz"}), }) nv, err := FromTyped(src, ref) require.NoError(t, err) // Assert foo has retained its location. - assert.Equal(t, config.NewValue("foo", config.Location{File: "foo"}), nv.Index(0)) + assert.Equal(t, dyn.NewValue("foo", dyn.Location{File: "foo"}), nv.Index(0)) // Assert bar lost its location (because it was overwritten). - assert.Equal(t, config.NewValue("bar", config.Location{}), nv.Index(1)) + assert.Equal(t, dyn.NewValue("bar", dyn.Location{}), nv.Index(1)) } func TestFromTypedStringEmpty(t *testing.T) { var src string - var ref = config.NilValue + var ref = dyn.NilValue nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.NilValue, nv) + assert.Equal(t, dyn.NilValue, nv) } func TestFromTypedStringEmptyOverwrite(t *testing.T) { var src string - var ref = config.V("old") + var ref = dyn.V("old") nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.V(""), nv) + assert.Equal(t, dyn.V(""), nv) } func TestFromTypedStringNonEmpty(t *testing.T) { var src string = "new" - var ref = config.NilValue + var ref = dyn.NilValue nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.V("new"), nv) + assert.Equal(t, dyn.V("new"), nv) } func TestFromTypedStringNonEmptyOverwrite(t *testing.T) { var src string = "new" - var ref = config.V("old") + var ref = dyn.V("old") nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.V("new"), nv) + assert.Equal(t, dyn.V("new"), nv) } func TestFromTypedStringRetainsLocationsIfUnchanged(t *testing.T) { var src string = "foo" - var ref = config.NewValue("foo", config.Location{File: "foo"}) + var ref = dyn.NewValue("foo", dyn.Location{File: "foo"}) nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.NewValue("foo", config.Location{File: "foo"}), nv) + assert.Equal(t, dyn.NewValue("foo", dyn.Location{File: "foo"}), nv) } func TestFromTypedStringTypeError(t *testing.T) { var src string = "foo" - var ref = config.V(1234) + var ref = dyn.V(1234) _, err := FromTyped(src, ref) require.Error(t, err) } func TestFromTypedBoolEmpty(t *testing.T) { var src bool - var ref = config.NilValue + var ref = dyn.NilValue nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.NilValue, nv) + assert.Equal(t, dyn.NilValue, nv) } func TestFromTypedBoolEmptyOverwrite(t *testing.T) { var src bool - var ref = config.V(true) + var ref = dyn.V(true) nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.V(false), nv) + assert.Equal(t, dyn.V(false), nv) } func TestFromTypedBoolNonEmpty(t *testing.T) { var src bool = true - var ref = config.NilValue + var ref = dyn.NilValue nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.V(true), nv) + assert.Equal(t, dyn.V(true), nv) } func TestFromTypedBoolNonEmptyOverwrite(t *testing.T) { var src bool = true - var ref = config.V(false) + var ref = dyn.V(false) nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.V(true), nv) + assert.Equal(t, dyn.V(true), nv) } func TestFromTypedBoolRetainsLocationsIfUnchanged(t *testing.T) { var src bool = true - var ref = config.NewValue(true, config.Location{File: "foo"}) + var ref = dyn.NewValue(true, dyn.Location{File: "foo"}) nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.NewValue(true, config.Location{File: "foo"}), nv) + assert.Equal(t, dyn.NewValue(true, dyn.Location{File: "foo"}), nv) } func TestFromTypedBoolTypeError(t *testing.T) { var src bool = true - var ref = config.V("string") + var ref = dyn.V("string") _, err := FromTyped(src, ref) require.Error(t, err) } func TestFromTypedIntEmpty(t *testing.T) { var src int - var ref = config.NilValue + var ref = dyn.NilValue nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.NilValue, nv) + assert.Equal(t, dyn.NilValue, nv) } func TestFromTypedIntEmptyOverwrite(t *testing.T) { var src int - var ref = config.V(1234) + var ref = dyn.V(1234) nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.V(int64(0)), nv) + assert.Equal(t, dyn.V(int64(0)), nv) } func TestFromTypedIntNonEmpty(t *testing.T) { var src int = 1234 - var ref = config.NilValue + var ref = dyn.NilValue nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.V(int64(1234)), nv) + assert.Equal(t, dyn.V(int64(1234)), nv) } func TestFromTypedIntNonEmptyOverwrite(t *testing.T) { var src int = 1234 - var ref = config.V(1233) + var ref = dyn.V(1233) nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.V(int64(1234)), nv) + assert.Equal(t, dyn.V(int64(1234)), nv) } func TestFromTypedIntRetainsLocationsIfUnchanged(t *testing.T) { var src int = 1234 - var ref = config.NewValue(1234, config.Location{File: "foo"}) + var ref = dyn.NewValue(1234, dyn.Location{File: "foo"}) nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.NewValue(1234, config.Location{File: "foo"}), nv) + assert.Equal(t, dyn.NewValue(1234, dyn.Location{File: "foo"}), nv) } func TestFromTypedIntTypeError(t *testing.T) { var src int = 1234 - var ref = config.V("string") + var ref = dyn.V("string") _, err := FromTyped(src, ref) require.Error(t, err) } func TestFromTypedFloatEmpty(t *testing.T) { var src float64 - var ref = config.NilValue + var ref = dyn.NilValue nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.NilValue, nv) + assert.Equal(t, dyn.NilValue, nv) } func TestFromTypedFloatEmptyOverwrite(t *testing.T) { var src float64 - var ref = config.V(1.23) + var ref = dyn.V(1.23) nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.V(0.0), nv) + assert.Equal(t, dyn.V(0.0), nv) } func TestFromTypedFloatNonEmpty(t *testing.T) { var src float64 = 1.23 - var ref = config.NilValue + var ref = dyn.NilValue nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.V(1.23), nv) + assert.Equal(t, dyn.V(1.23), nv) } func TestFromTypedFloatNonEmptyOverwrite(t *testing.T) { var src float64 = 1.23 - var ref = config.V(1.24) + var ref = dyn.V(1.24) nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.V(1.23), nv) + assert.Equal(t, dyn.V(1.23), nv) } func TestFromTypedFloatRetainsLocationsIfUnchanged(t *testing.T) { var src float64 = 1.23 - var ref = config.NewValue(1.23, config.Location{File: "foo"}) + var ref = dyn.NewValue(1.23, dyn.Location{File: "foo"}) nv, err := FromTyped(src, ref) require.NoError(t, err) - assert.Equal(t, config.NewValue(1.23, config.Location{File: "foo"}), nv) + assert.Equal(t, dyn.NewValue(1.23, dyn.Location{File: "foo"}), nv) } func TestFromTypedFloatTypeError(t *testing.T) { var src float64 = 1.23 - var ref = config.V("string") + var ref = dyn.V("string") _, err := FromTyped(src, ref) require.Error(t, err) } diff --git a/libs/config/convert/normalize.go b/libs/dyn/convert/normalize.go similarity index 58% rename from libs/config/convert/normalize.go rename to libs/dyn/convert/normalize.go index d7d2b1df..7a652cbc 100644 --- a/libs/config/convert/normalize.go +++ b/libs/dyn/convert/normalize.go @@ -5,15 +5,15 @@ import ( "reflect" "strconv" - "github.com/databricks/cli/libs/config" "github.com/databricks/cli/libs/diag" + "github.com/databricks/cli/libs/dyn" ) -func Normalize(dst any, src config.Value) (config.Value, diag.Diagnostics) { +func Normalize(dst any, src dyn.Value) (dyn.Value, diag.Diagnostics) { return normalizeType(reflect.TypeOf(dst), src) } -func normalizeType(typ reflect.Type, src config.Value) (config.Value, diag.Diagnostics) { +func normalizeType(typ reflect.Type, src dyn.Value) (dyn.Value, diag.Diagnostics) { for typ.Kind() == reflect.Pointer { typ = typ.Elem() } @@ -35,10 +35,10 @@ func normalizeType(typ reflect.Type, src config.Value) (config.Value, diag.Diagn return normalizeFloat(typ, src) } - return config.NilValue, diag.Errorf("unsupported type: %s", typ.Kind()) + return dyn.NilValue, diag.Errorf("unsupported type: %s", typ.Kind()) } -func typeMismatch(expected config.Kind, src config.Value) diag.Diagnostic { +func typeMismatch(expected dyn.Kind, src dyn.Value) diag.Diagnostic { return diag.Diagnostic{ Severity: diag.Error, Summary: fmt.Sprintf("expected %s, found %s", expected, src.Kind()), @@ -46,12 +46,12 @@ func typeMismatch(expected config.Kind, src config.Value) diag.Diagnostic { } } -func normalizeStruct(typ reflect.Type, src config.Value) (config.Value, diag.Diagnostics) { +func normalizeStruct(typ reflect.Type, src dyn.Value) (dyn.Value, diag.Diagnostics) { var diags diag.Diagnostics switch src.Kind() { - case config.KindMap: - out := make(map[string]config.Value) + case dyn.KindMap: + out := make(map[string]dyn.Value) info := getStructInfo(typ) for k, v := range src.MustMap() { index, ok := info.Fields[k] @@ -77,20 +77,20 @@ func normalizeStruct(typ reflect.Type, src config.Value) (config.Value, diag.Dia out[k] = v } - return config.NewValue(out, src.Location()), diags - case config.KindNil: + return dyn.NewValue(out, src.Location()), diags + case dyn.KindNil: return src, diags } - return config.NilValue, diags.Append(typeMismatch(config.KindMap, src)) + return dyn.NilValue, diags.Append(typeMismatch(dyn.KindMap, src)) } -func normalizeMap(typ reflect.Type, src config.Value) (config.Value, diag.Diagnostics) { +func normalizeMap(typ reflect.Type, src dyn.Value) (dyn.Value, diag.Diagnostics) { var diags diag.Diagnostics switch src.Kind() { - case config.KindMap: - out := make(map[string]config.Value) + case dyn.KindMap: + out := make(map[string]dyn.Value) for k, v := range src.MustMap() { // Normalize the value according to the map element type. v, err := normalizeType(typ.Elem(), v) @@ -105,20 +105,20 @@ func normalizeMap(typ reflect.Type, src config.Value) (config.Value, diag.Diagno out[k] = v } - return config.NewValue(out, src.Location()), diags - case config.KindNil: + return dyn.NewValue(out, src.Location()), diags + case dyn.KindNil: return src, diags } - return config.NilValue, diags.Append(typeMismatch(config.KindMap, src)) + return dyn.NilValue, diags.Append(typeMismatch(dyn.KindMap, src)) } -func normalizeSlice(typ reflect.Type, src config.Value) (config.Value, diag.Diagnostics) { +func normalizeSlice(typ reflect.Type, src dyn.Value) (dyn.Value, diag.Diagnostics) { var diags diag.Diagnostics switch src.Kind() { - case config.KindSequence: - out := make([]config.Value, 0, len(src.MustSequence())) + case dyn.KindSequence: + out := make([]dyn.Value, 0, len(src.MustSequence())) for _, v := range src.MustSequence() { // Normalize the value according to the slice element type. v, err := normalizeType(typ.Elem(), v) @@ -133,42 +133,42 @@ func normalizeSlice(typ reflect.Type, src config.Value) (config.Value, diag.Diag out = append(out, v) } - return config.NewValue(out, src.Location()), diags - case config.KindNil: + return dyn.NewValue(out, src.Location()), diags + case dyn.KindNil: return src, diags } - return config.NilValue, diags.Append(typeMismatch(config.KindSequence, src)) + return dyn.NilValue, diags.Append(typeMismatch(dyn.KindSequence, src)) } -func normalizeString(typ reflect.Type, src config.Value) (config.Value, diag.Diagnostics) { +func normalizeString(typ reflect.Type, src dyn.Value) (dyn.Value, diag.Diagnostics) { var diags diag.Diagnostics var out string switch src.Kind() { - case config.KindString: + case dyn.KindString: out = src.MustString() - case config.KindBool: + case dyn.KindBool: out = strconv.FormatBool(src.MustBool()) - case config.KindInt: + case dyn.KindInt: out = strconv.FormatInt(src.MustInt(), 10) - case config.KindFloat: + case dyn.KindFloat: out = strconv.FormatFloat(src.MustFloat(), 'f', -1, 64) default: - return config.NilValue, diags.Append(typeMismatch(config.KindString, src)) + return dyn.NilValue, diags.Append(typeMismatch(dyn.KindString, src)) } - return config.NewValue(out, src.Location()), diags + return dyn.NewValue(out, src.Location()), diags } -func normalizeBool(typ reflect.Type, src config.Value) (config.Value, diag.Diagnostics) { +func normalizeBool(typ reflect.Type, src dyn.Value) (dyn.Value, diag.Diagnostics) { var diags diag.Diagnostics var out bool switch src.Kind() { - case config.KindBool: + case dyn.KindBool: out = src.MustBool() - case config.KindString: + case dyn.KindString: // See https://github.com/go-yaml/yaml/blob/f6f7691b1fdeb513f56608cd2c32c51f8194bf51/decode.go#L684-L693. switch src.MustString() { case "true", "y", "Y", "yes", "Yes", "YES", "on", "On", "ON": @@ -177,59 +177,59 @@ func normalizeBool(typ reflect.Type, src config.Value) (config.Value, diag.Diagn out = false default: // Cannot interpret as a boolean. - return config.NilValue, diags.Append(typeMismatch(config.KindBool, src)) + return dyn.NilValue, diags.Append(typeMismatch(dyn.KindBool, src)) } default: - return config.NilValue, diags.Append(typeMismatch(config.KindBool, src)) + return dyn.NilValue, diags.Append(typeMismatch(dyn.KindBool, src)) } - return config.NewValue(out, src.Location()), diags + return dyn.NewValue(out, src.Location()), diags } -func normalizeInt(typ reflect.Type, src config.Value) (config.Value, diag.Diagnostics) { +func normalizeInt(typ reflect.Type, src dyn.Value) (dyn.Value, diag.Diagnostics) { var diags diag.Diagnostics var out int64 switch src.Kind() { - case config.KindInt: + case dyn.KindInt: out = src.MustInt() - case config.KindString: + case dyn.KindString: var err error out, err = strconv.ParseInt(src.MustString(), 10, 64) if err != nil { - return config.NilValue, diags.Append(diag.Diagnostic{ + return dyn.NilValue, diags.Append(diag.Diagnostic{ Severity: diag.Error, Summary: fmt.Sprintf("cannot parse %q as an integer", src.MustString()), Location: src.Location(), }) } default: - return config.NilValue, diags.Append(typeMismatch(config.KindInt, src)) + return dyn.NilValue, diags.Append(typeMismatch(dyn.KindInt, src)) } - return config.NewValue(out, src.Location()), diags + return dyn.NewValue(out, src.Location()), diags } -func normalizeFloat(typ reflect.Type, src config.Value) (config.Value, diag.Diagnostics) { +func normalizeFloat(typ reflect.Type, src dyn.Value) (dyn.Value, diag.Diagnostics) { var diags diag.Diagnostics var out float64 switch src.Kind() { - case config.KindFloat: + case dyn.KindFloat: out = src.MustFloat() - case config.KindString: + case dyn.KindString: var err error out, err = strconv.ParseFloat(src.MustString(), 64) if err != nil { - return config.NilValue, diags.Append(diag.Diagnostic{ + return dyn.NilValue, diags.Append(diag.Diagnostic{ Severity: diag.Error, Summary: fmt.Sprintf("cannot parse %q as a floating point number", src.MustString()), Location: src.Location(), }) } default: - return config.NilValue, diags.Append(typeMismatch(config.KindFloat, src)) + return dyn.NilValue, diags.Append(typeMismatch(dyn.KindFloat, src)) } - return config.NewValue(out, src.Location()), diags + return dyn.NewValue(out, src.Location()), diags } diff --git a/libs/config/convert/normalize_test.go b/libs/dyn/convert/normalize_test.go similarity index 74% rename from libs/config/convert/normalize_test.go rename to libs/dyn/convert/normalize_test.go index 9c4b10bb..13b1ed52 100644 --- a/libs/config/convert/normalize_test.go +++ b/libs/dyn/convert/normalize_test.go @@ -3,8 +3,8 @@ package convert import ( "testing" - "github.com/databricks/cli/libs/config" "github.com/databricks/cli/libs/diag" + "github.com/databricks/cli/libs/dyn" "github.com/stretchr/testify/assert" ) @@ -15,9 +15,9 @@ func TestNormalizeStruct(t *testing.T) { } var typ Tmp - vin := config.V(map[string]config.Value{ - "foo": config.V("bar"), - "bar": config.V("baz"), + vin := dyn.V(map[string]dyn.Value{ + "foo": dyn.V("bar"), + "bar": dyn.V("baz"), }) vout, err := Normalize(typ, vin) @@ -32,9 +32,9 @@ func TestNormalizeStructElementDiagnostic(t *testing.T) { } var typ Tmp - vin := config.V(map[string]config.Value{ - "foo": config.V("bar"), - "bar": config.V(map[string]config.Value{"an": config.V("error")}), + vin := dyn.V(map[string]dyn.Value{ + "foo": dyn.V("bar"), + "bar": dyn.V(map[string]dyn.Value{"an": dyn.V("error")}), }) vout, err := Normalize(typ, vin) @@ -42,7 +42,7 @@ func TestNormalizeStructElementDiagnostic(t *testing.T) { assert.Equal(t, diag.Diagnostic{ Severity: diag.Error, Summary: `expected string, found map`, - Location: config.Location{}, + Location: dyn.Location{}, }, err[0]) // Elements that encounter an error during normalization are dropped. @@ -57,9 +57,9 @@ func TestNormalizeStructUnknownField(t *testing.T) { } var typ Tmp - vin := config.V(map[string]config.Value{ - "foo": config.V("bar"), - "bar": config.V("baz"), + vin := dyn.V(map[string]dyn.Value{ + "foo": dyn.V("bar"), + "bar": dyn.V("baz"), }) vout, err := Normalize(typ, vin) @@ -82,7 +82,7 @@ func TestNormalizeStructNil(t *testing.T) { } var typ Tmp - vin := config.NilValue + vin := dyn.NilValue vout, err := Normalize(typ, vin) assert.Empty(t, err) assert.Equal(t, vin, vout) @@ -94,7 +94,7 @@ func TestNormalizeStructError(t *testing.T) { } var typ Tmp - vin := config.V("string") + vin := dyn.V("string") _, err := Normalize(typ, vin) assert.Len(t, err, 1) assert.Equal(t, diag.Diagnostic{ @@ -106,9 +106,9 @@ func TestNormalizeStructError(t *testing.T) { func TestNormalizeMap(t *testing.T) { var typ map[string]string - vin := config.V(map[string]config.Value{ - "foo": config.V("bar"), - "bar": config.V("baz"), + vin := dyn.V(map[string]dyn.Value{ + "foo": dyn.V("bar"), + "bar": dyn.V("baz"), }) vout, err := Normalize(typ, vin) @@ -118,9 +118,9 @@ func TestNormalizeMap(t *testing.T) { func TestNormalizeMapElementDiagnostic(t *testing.T) { var typ map[string]string - vin := config.V(map[string]config.Value{ - "foo": config.V("bar"), - "bar": config.V(map[string]config.Value{"an": config.V("error")}), + vin := dyn.V(map[string]dyn.Value{ + "foo": dyn.V("bar"), + "bar": dyn.V(map[string]dyn.Value{"an": dyn.V("error")}), }) vout, err := Normalize(typ, vin) @@ -128,7 +128,7 @@ func TestNormalizeMapElementDiagnostic(t *testing.T) { assert.Equal(t, diag.Diagnostic{ Severity: diag.Error, Summary: `expected string, found map`, - Location: config.Location{}, + Location: dyn.Location{}, }, err[0]) // Elements that encounter an error during normalization are dropped. @@ -139,7 +139,7 @@ func TestNormalizeMapElementDiagnostic(t *testing.T) { func TestNormalizeMapNil(t *testing.T) { var typ map[string]string - vin := config.NilValue + vin := dyn.NilValue vout, err := Normalize(typ, vin) assert.Empty(t, err) assert.Equal(t, vin, vout) @@ -147,7 +147,7 @@ func TestNormalizeMapNil(t *testing.T) { func TestNormalizeMapError(t *testing.T) { var typ map[string]string - vin := config.V("string") + vin := dyn.V("string") _, err := Normalize(typ, vin) assert.Len(t, err, 1) assert.Equal(t, diag.Diagnostic{ @@ -159,9 +159,9 @@ func TestNormalizeMapError(t *testing.T) { func TestNormalizeSlice(t *testing.T) { var typ []string - vin := config.V([]config.Value{ - config.V("foo"), - config.V("bar"), + vin := dyn.V([]dyn.Value{ + dyn.V("foo"), + dyn.V("bar"), }) vout, err := Normalize(typ, vin) @@ -171,10 +171,10 @@ func TestNormalizeSlice(t *testing.T) { func TestNormalizeSliceElementDiagnostic(t *testing.T) { var typ []string - vin := config.V([]config.Value{ - config.V("foo"), - config.V("bar"), - config.V(map[string]config.Value{"an": config.V("error")}), + vin := dyn.V([]dyn.Value{ + dyn.V("foo"), + dyn.V("bar"), + dyn.V(map[string]dyn.Value{"an": dyn.V("error")}), }) vout, err := Normalize(typ, vin) @@ -182,7 +182,7 @@ func TestNormalizeSliceElementDiagnostic(t *testing.T) { assert.Equal(t, diag.Diagnostic{ Severity: diag.Error, Summary: `expected string, found map`, - Location: config.Location{}, + Location: dyn.Location{}, }, err[0]) // Elements that encounter an error during normalization are dropped. @@ -191,7 +191,7 @@ func TestNormalizeSliceElementDiagnostic(t *testing.T) { func TestNormalizeSliceNil(t *testing.T) { var typ []string - vin := config.NilValue + vin := dyn.NilValue vout, err := Normalize(typ, vin) assert.Empty(t, err) assert.Equal(t, vin, vout) @@ -199,7 +199,7 @@ func TestNormalizeSliceNil(t *testing.T) { func TestNormalizeSliceError(t *testing.T) { var typ []string - vin := config.V("string") + vin := dyn.V("string") _, err := Normalize(typ, vin) assert.Len(t, err, 1) assert.Equal(t, diag.Diagnostic{ @@ -211,7 +211,7 @@ func TestNormalizeSliceError(t *testing.T) { func TestNormalizeString(t *testing.T) { var typ string - vin := config.V("string") + vin := dyn.V("string") vout, err := Normalize(&typ, vin) assert.Empty(t, err) assert.Equal(t, vin, vout) @@ -219,7 +219,7 @@ func TestNormalizeString(t *testing.T) { func TestNormalizeStringNil(t *testing.T) { var typ string - vin := config.NewValue(nil, config.Location{File: "file", Line: 1, Column: 1}) + vin := dyn.NewValue(nil, dyn.Location{File: "file", Line: 1, Column: 1}) _, err := Normalize(&typ, vin) assert.Len(t, err, 1) assert.Equal(t, diag.Diagnostic{ @@ -231,51 +231,51 @@ func TestNormalizeStringNil(t *testing.T) { func TestNormalizeStringFromBool(t *testing.T) { var typ string - vin := config.NewValue(true, config.Location{File: "file", Line: 1, Column: 1}) + vin := dyn.NewValue(true, dyn.Location{File: "file", Line: 1, Column: 1}) vout, err := Normalize(&typ, vin) assert.Empty(t, err) - assert.Equal(t, config.NewValue("true", vin.Location()), vout) + assert.Equal(t, dyn.NewValue("true", vin.Location()), vout) } func TestNormalizeStringFromInt(t *testing.T) { var typ string - vin := config.NewValue(123, config.Location{File: "file", Line: 1, Column: 1}) + vin := dyn.NewValue(123, dyn.Location{File: "file", Line: 1, Column: 1}) vout, err := Normalize(&typ, vin) assert.Empty(t, err) - assert.Equal(t, config.NewValue("123", vin.Location()), vout) + assert.Equal(t, dyn.NewValue("123", vin.Location()), vout) } func TestNormalizeStringFromFloat(t *testing.T) { var typ string - vin := config.NewValue(1.20, config.Location{File: "file", Line: 1, Column: 1}) + vin := dyn.NewValue(1.20, dyn.Location{File: "file", Line: 1, Column: 1}) vout, err := Normalize(&typ, vin) assert.Empty(t, err) - assert.Equal(t, config.NewValue("1.2", vin.Location()), vout) + assert.Equal(t, dyn.NewValue("1.2", vin.Location()), vout) } func TestNormalizeStringError(t *testing.T) { var typ string - vin := config.V(map[string]config.Value{"an": config.V("error")}) + vin := dyn.V(map[string]dyn.Value{"an": dyn.V("error")}) _, err := Normalize(&typ, vin) assert.Len(t, err, 1) assert.Equal(t, diag.Diagnostic{ Severity: diag.Error, Summary: `expected string, found map`, - Location: config.Location{}, + Location: dyn.Location{}, }, err[0]) } func TestNormalizeBool(t *testing.T) { var typ bool - vin := config.V(true) + vin := dyn.V(true) vout, err := Normalize(&typ, vin) assert.Empty(t, err) - assert.Equal(t, config.V(true), vout) + assert.Equal(t, dyn.V(true), vout) } func TestNormalizeBoolNil(t *testing.T) { var typ bool - vin := config.NewValue(nil, config.Location{File: "file", Line: 1, Column: 1}) + vin := dyn.NewValue(nil, dyn.Location{File: "file", Line: 1, Column: 1}) _, err := Normalize(&typ, vin) assert.Len(t, err, 1) assert.Equal(t, diag.Diagnostic{ @@ -299,16 +299,16 @@ func TestNormalizeBoolFromString(t *testing.T) { {"on", true}, {"off", false}, } { - vin := config.V(c.Input) + vin := dyn.V(c.Input) vout, err := Normalize(&typ, vin) assert.Empty(t, err) - assert.Equal(t, config.V(c.Output), vout) + assert.Equal(t, dyn.V(c.Output), vout) } } func TestNormalizeBoolFromStringError(t *testing.T) { var typ bool - vin := config.V("abc") + vin := dyn.V("abc") _, err := Normalize(&typ, vin) assert.Len(t, err, 1) assert.Equal(t, diag.Diagnostic{ @@ -320,27 +320,27 @@ func TestNormalizeBoolFromStringError(t *testing.T) { func TestNormalizeBoolError(t *testing.T) { var typ bool - vin := config.V(map[string]config.Value{"an": config.V("error")}) + vin := dyn.V(map[string]dyn.Value{"an": dyn.V("error")}) _, err := Normalize(&typ, vin) assert.Len(t, err, 1) assert.Equal(t, diag.Diagnostic{ Severity: diag.Error, Summary: `expected bool, found map`, - Location: config.Location{}, + Location: dyn.Location{}, }, err[0]) } func TestNormalizeInt(t *testing.T) { var typ int - vin := config.V(123) + vin := dyn.V(123) vout, err := Normalize(&typ, vin) assert.Empty(t, err) - assert.Equal(t, config.V(int64(123)), vout) + assert.Equal(t, dyn.V(int64(123)), vout) } func TestNormalizeIntNil(t *testing.T) { var typ int - vin := config.NewValue(nil, config.Location{File: "file", Line: 1, Column: 1}) + vin := dyn.NewValue(nil, dyn.Location{File: "file", Line: 1, Column: 1}) _, err := Normalize(&typ, vin) assert.Len(t, err, 1) assert.Equal(t, diag.Diagnostic{ @@ -352,15 +352,15 @@ func TestNormalizeIntNil(t *testing.T) { func TestNormalizeIntFromString(t *testing.T) { var typ int - vin := config.V("123") + vin := dyn.V("123") vout, err := Normalize(&typ, vin) assert.Empty(t, err) - assert.Equal(t, config.V(int64(123)), vout) + assert.Equal(t, dyn.V(int64(123)), vout) } func TestNormalizeIntFromStringError(t *testing.T) { var typ int - vin := config.V("abc") + vin := dyn.V("abc") _, err := Normalize(&typ, vin) assert.Len(t, err, 1) assert.Equal(t, diag.Diagnostic{ @@ -372,27 +372,27 @@ func TestNormalizeIntFromStringError(t *testing.T) { func TestNormalizeIntError(t *testing.T) { var typ int - vin := config.V(map[string]config.Value{"an": config.V("error")}) + vin := dyn.V(map[string]dyn.Value{"an": dyn.V("error")}) _, err := Normalize(&typ, vin) assert.Len(t, err, 1) assert.Equal(t, diag.Diagnostic{ Severity: diag.Error, Summary: `expected int, found map`, - Location: config.Location{}, + Location: dyn.Location{}, }, err[0]) } func TestNormalizeFloat(t *testing.T) { var typ float64 - vin := config.V(1.2) + vin := dyn.V(1.2) vout, err := Normalize(&typ, vin) assert.Empty(t, err) - assert.Equal(t, config.V(1.2), vout) + assert.Equal(t, dyn.V(1.2), vout) } func TestNormalizeFloatNil(t *testing.T) { var typ float64 - vin := config.NewValue(nil, config.Location{File: "file", Line: 1, Column: 1}) + vin := dyn.NewValue(nil, dyn.Location{File: "file", Line: 1, Column: 1}) _, err := Normalize(&typ, vin) assert.Len(t, err, 1) assert.Equal(t, diag.Diagnostic{ @@ -404,15 +404,15 @@ func TestNormalizeFloatNil(t *testing.T) { func TestNormalizeFloatFromString(t *testing.T) { var typ float64 - vin := config.V("1.2") + vin := dyn.V("1.2") vout, err := Normalize(&typ, vin) assert.Empty(t, err) - assert.Equal(t, config.V(1.2), vout) + assert.Equal(t, dyn.V(1.2), vout) } func TestNormalizeFloatFromStringError(t *testing.T) { var typ float64 - vin := config.V("abc") + vin := dyn.V("abc") _, err := Normalize(&typ, vin) assert.Len(t, err, 1) assert.Equal(t, diag.Diagnostic{ @@ -424,12 +424,12 @@ func TestNormalizeFloatFromStringError(t *testing.T) { func TestNormalizeFloatError(t *testing.T) { var typ float64 - vin := config.V(map[string]config.Value{"an": config.V("error")}) + vin := dyn.V(map[string]dyn.Value{"an": dyn.V("error")}) _, err := Normalize(&typ, vin) assert.Len(t, err, 1) assert.Equal(t, diag.Diagnostic{ Severity: diag.Error, Summary: `expected float, found map`, - Location: config.Location{}, + Location: dyn.Location{}, }, err[0]) } diff --git a/libs/config/convert/struct_info.go b/libs/dyn/convert/struct_info.go similarity index 87% rename from libs/config/convert/struct_info.go rename to libs/dyn/convert/struct_info.go index 80cfabb6..dc3ed4da 100644 --- a/libs/config/convert/struct_info.go +++ b/libs/dyn/convert/struct_info.go @@ -5,16 +5,16 @@ import ( "strings" "sync" - "github.com/databricks/cli/libs/config" + "github.com/databricks/cli/libs/dyn" ) // structInfo holds the type information we need to efficiently -// convert data from a [config.Value] to a Go struct. +// convert data from a [dyn.Value] to a Go struct. type structInfo struct { // Fields maps the JSON-name of the field to the field's index for use with [FieldByIndex]. Fields map[string][]int - // ValueField maps to the field with a [config.Value]. + // ValueField maps to the field with a [dyn.Value]. // The underlying type is expected to only have one of these. ValueField []int } @@ -74,10 +74,10 @@ func buildStructInfo(typ reflect.Type) structInfo { continue } - // If this field has type [config.Value], we populate it with the source [config.Value] from [ToTyped]. + // If this field has type [dyn.Value], we populate it with the source [dyn.Value] from [ToTyped]. if sf.IsExported() && sf.Type == configValueType { if out.ValueField != nil { - panic("multiple config.Value fields") + panic("multiple dyn.Value fields") } out.ValueField = append(prefix, sf.Index...) continue @@ -129,5 +129,5 @@ func (s *structInfo) FieldValues(v reflect.Value) map[string]reflect.Value { return out } -// Type of [config.Value]. -var configValueType = reflect.TypeOf((*config.Value)(nil)).Elem() +// Type of [dyn.Value]. +var configValueType = reflect.TypeOf((*dyn.Value)(nil)).Elem() diff --git a/libs/config/convert/struct_info_test.go b/libs/dyn/convert/struct_info_test.go similarity index 97% rename from libs/config/convert/struct_info_test.go rename to libs/dyn/convert/struct_info_test.go index 685679ae..08be3c47 100644 --- a/libs/config/convert/struct_info_test.go +++ b/libs/dyn/convert/struct_info_test.go @@ -4,7 +4,7 @@ import ( "reflect" "testing" - "github.com/databricks/cli/libs/config" + "github.com/databricks/cli/libs/dyn" "github.com/stretchr/testify/assert" ) @@ -207,7 +207,7 @@ func TestStructInfoValueFieldAbsent(t *testing.T) { func TestStructInfoValueFieldPresent(t *testing.T) { type Tmp struct { - Foo config.Value + Foo dyn.Value } si := getStructInfo(reflect.TypeOf(Tmp{})) @@ -216,8 +216,8 @@ func TestStructInfoValueFieldPresent(t *testing.T) { func TestStructInfoValueFieldMultiple(t *testing.T) { type Tmp struct { - Foo config.Value - Bar config.Value + Foo dyn.Value + Bar dyn.Value } assert.Panics(t, func() { diff --git a/libs/config/convert/to_typed.go b/libs/dyn/convert/to_typed.go similarity index 81% rename from libs/config/convert/to_typed.go rename to libs/dyn/convert/to_typed.go index 8c43d974..209de12c 100644 --- a/libs/config/convert/to_typed.go +++ b/libs/dyn/convert/to_typed.go @@ -5,17 +5,17 @@ import ( "reflect" "strconv" - "github.com/databricks/cli/libs/config" + "github.com/databricks/cli/libs/dyn" ) -func ToTyped(dst any, src config.Value) error { +func ToTyped(dst any, src dyn.Value) error { dstv := reflect.ValueOf(dst) // Dereference pointer if necessary for dstv.Kind() == reflect.Pointer { // If the source value is nil and the destination is a settable pointer, // set the destination to nil. Also see `end_to_end_test.go`. - if dstv.CanSet() && src == config.NilValue { + if dstv.CanSet() && src == dyn.NilValue { dstv.SetZero() return nil } @@ -50,9 +50,9 @@ func ToTyped(dst any, src config.Value) error { return fmt.Errorf("unsupported type: %s", dstv.Kind()) } -func toTypedStruct(dst reflect.Value, src config.Value) error { +func toTypedStruct(dst reflect.Value, src dyn.Value) error { switch src.Kind() { - case config.KindMap: + case dyn.KindMap: info := getStructInfo(dst.Type()) for k, v := range src.MustMap() { index, ok := info.Fields[k] @@ -83,14 +83,14 @@ func toTypedStruct(dst reflect.Value, src config.Value) error { } } - // Populate field(s) for [config.Value], if any. + // Populate field(s) for [dyn.Value], if any. if info.ValueField != nil { vv := dst.FieldByIndex(info.ValueField) vv.Set(reflect.ValueOf(src)) } return nil - case config.KindNil: + case dyn.KindNil: dst.SetZero() return nil } @@ -101,9 +101,9 @@ func toTypedStruct(dst reflect.Value, src config.Value) error { } } -func toTypedMap(dst reflect.Value, src config.Value) error { +func toTypedMap(dst reflect.Value, src dyn.Value) error { switch src.Kind() { - case config.KindMap: + case dyn.KindMap: m := src.MustMap() // Always overwrite. @@ -118,7 +118,7 @@ func toTypedMap(dst reflect.Value, src config.Value) error { dst.SetMapIndex(kv, vv.Elem()) } return nil - case config.KindNil: + case dyn.KindNil: dst.SetZero() return nil } @@ -129,9 +129,9 @@ func toTypedMap(dst reflect.Value, src config.Value) error { } } -func toTypedSlice(dst reflect.Value, src config.Value) error { +func toTypedSlice(dst reflect.Value, src dyn.Value) error { switch src.Kind() { - case config.KindSequence: + case dyn.KindSequence: seq := src.MustSequence() // Always overwrite. @@ -143,7 +143,7 @@ func toTypedSlice(dst reflect.Value, src config.Value) error { } } return nil - case config.KindNil: + case dyn.KindNil: dst.SetZero() return nil } @@ -154,18 +154,18 @@ func toTypedSlice(dst reflect.Value, src config.Value) error { } } -func toTypedString(dst reflect.Value, src config.Value) error { +func toTypedString(dst reflect.Value, src dyn.Value) error { switch src.Kind() { - case config.KindString: + case dyn.KindString: dst.SetString(src.MustString()) return nil - case config.KindBool: + case dyn.KindBool: dst.SetString(strconv.FormatBool(src.MustBool())) return nil - case config.KindInt: + case dyn.KindInt: dst.SetString(strconv.FormatInt(src.MustInt(), 10)) return nil - case config.KindFloat: + case dyn.KindFloat: dst.SetString(strconv.FormatFloat(src.MustFloat(), 'f', -1, 64)) return nil } @@ -176,12 +176,12 @@ func toTypedString(dst reflect.Value, src config.Value) error { } } -func toTypedBool(dst reflect.Value, src config.Value) error { +func toTypedBool(dst reflect.Value, src dyn.Value) error { switch src.Kind() { - case config.KindBool: + case dyn.KindBool: dst.SetBool(src.MustBool()) return nil - case config.KindString: + case dyn.KindString: // See https://github.com/go-yaml/yaml/blob/f6f7691b1fdeb513f56608cd2c32c51f8194bf51/decode.go#L684-L693. switch src.MustString() { case "y", "Y", "yes", "Yes", "YES", "on", "On", "ON": @@ -199,12 +199,12 @@ func toTypedBool(dst reflect.Value, src config.Value) error { } } -func toTypedInt(dst reflect.Value, src config.Value) error { +func toTypedInt(dst reflect.Value, src dyn.Value) error { switch src.Kind() { - case config.KindInt: + case dyn.KindInt: dst.SetInt(src.MustInt()) return nil - case config.KindString: + case dyn.KindString: if i64, err := strconv.ParseInt(src.MustString(), 10, 64); err == nil { dst.SetInt(i64) return nil @@ -217,12 +217,12 @@ func toTypedInt(dst reflect.Value, src config.Value) error { } } -func toTypedFloat(dst reflect.Value, src config.Value) error { +func toTypedFloat(dst reflect.Value, src dyn.Value) error { switch src.Kind() { - case config.KindFloat: + case dyn.KindFloat: dst.SetFloat(src.MustFloat()) return nil - case config.KindString: + case dyn.KindString: if f64, err := strconv.ParseFloat(src.MustString(), 64); err == nil { dst.SetFloat(f64) return nil diff --git a/libs/config/convert/to_typed_test.go b/libs/dyn/convert/to_typed_test.go similarity index 76% rename from libs/config/convert/to_typed_test.go rename to libs/dyn/convert/to_typed_test.go index 2845bdda..3adc94c7 100644 --- a/libs/config/convert/to_typed_test.go +++ b/libs/dyn/convert/to_typed_test.go @@ -3,7 +3,7 @@ package convert import ( "testing" - "github.com/databricks/cli/libs/config" + "github.com/databricks/cli/libs/dyn" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -21,9 +21,9 @@ func TestToTypedStruct(t *testing.T) { } var out Tmp - v := config.V(map[string]config.Value{ - "foo": config.V("bar"), - "bar": config.V("baz"), + v := dyn.V(map[string]dyn.Value{ + "foo": dyn.V("bar"), + "bar": dyn.V("baz"), }) err := ToTyped(&out, v) @@ -48,9 +48,9 @@ func TestToTypedStructOverwrite(t *testing.T) { Foo: "baz", Bar: "qux", } - v := config.V(map[string]config.Value{ - "foo": config.V("bar"), - "bar": config.V("baz"), + v := dyn.V(map[string]dyn.Value{ + "foo": dyn.V("bar"), + "bar": dyn.V("baz"), }) err := ToTyped(&out, v) @@ -74,9 +74,9 @@ func TestToTypedStructAnonymousByValue(t *testing.T) { } var out Tmp - v := config.V(map[string]config.Value{ - "foo": config.V("bar"), - "bar": config.V("baz"), + v := dyn.V(map[string]dyn.Value{ + "foo": dyn.V("bar"), + "bar": dyn.V("baz"), }) err := ToTyped(&out, v) @@ -100,9 +100,9 @@ func TestToTypedStructAnonymousByPointer(t *testing.T) { } var out Tmp - v := config.V(map[string]config.Value{ - "foo": config.V("bar"), - "bar": config.V("baz"), + v := dyn.V(map[string]dyn.Value{ + "foo": dyn.V("bar"), + "bar": dyn.V("baz"), }) err := ToTyped(&out, v) @@ -117,7 +117,7 @@ func TestToTypedStructNil(t *testing.T) { } var out = Tmp{} - err := ToTyped(&out, config.NilValue) + err := ToTyped(&out, dyn.NilValue) require.NoError(t, err) assert.Equal(t, Tmp{}, out) } @@ -128,7 +128,7 @@ func TestToTypedStructNilOverwrite(t *testing.T) { } var out = Tmp{"bar"} - err := ToTyped(&out, config.NilValue) + err := ToTyped(&out, dyn.NilValue) require.NoError(t, err) assert.Equal(t, Tmp{}, out) } @@ -137,12 +137,12 @@ func TestToTypedStructWithValueField(t *testing.T) { type Tmp struct { Foo string `json:"foo"` - ConfigValue config.Value + ConfigValue dyn.Value } var out Tmp - v := config.V(map[string]config.Value{ - "foo": config.V("bar"), + v := dyn.V(map[string]dyn.Value{ + "foo": dyn.V("bar"), }) err := ToTyped(&out, v) @@ -154,8 +154,8 @@ func TestToTypedStructWithValueField(t *testing.T) { func TestToTypedMap(t *testing.T) { var out = map[string]string{} - v := config.V(map[string]config.Value{ - "key": config.V("value"), + v := dyn.V(map[string]dyn.Value{ + "key": dyn.V("value"), }) err := ToTyped(&out, v) @@ -169,8 +169,8 @@ func TestToTypedMapOverwrite(t *testing.T) { "foo": "bar", } - v := config.V(map[string]config.Value{ - "bar": config.V("qux"), + v := dyn.V(map[string]dyn.Value{ + "bar": dyn.V("qux"), }) err := ToTyped(&out, v) @@ -182,8 +182,8 @@ func TestToTypedMapOverwrite(t *testing.T) { func TestToTypedMapWithPointerElement(t *testing.T) { var out map[string]*string - v := config.V(map[string]config.Value{ - "key": config.V("value"), + v := dyn.V(map[string]dyn.Value{ + "key": dyn.V("value"), }) err := ToTyped(&out, v) @@ -194,7 +194,7 @@ func TestToTypedMapWithPointerElement(t *testing.T) { func TestToTypedMapNil(t *testing.T) { var out = map[string]string{} - err := ToTyped(&out, config.NilValue) + err := ToTyped(&out, dyn.NilValue) require.NoError(t, err) assert.Nil(t, out) } @@ -203,7 +203,7 @@ func TestToTypedMapNilOverwrite(t *testing.T) { var out = map[string]string{ "foo": "bar", } - err := ToTyped(&out, config.NilValue) + err := ToTyped(&out, dyn.NilValue) require.NoError(t, err) assert.Nil(t, out) } @@ -211,9 +211,9 @@ func TestToTypedMapNilOverwrite(t *testing.T) { func TestToTypedSlice(t *testing.T) { var out []string - v := config.V([]config.Value{ - config.V("foo"), - config.V("bar"), + v := dyn.V([]dyn.Value{ + dyn.V("foo"), + dyn.V("bar"), }) err := ToTyped(&out, v) @@ -226,9 +226,9 @@ func TestToTypedSlice(t *testing.T) { func TestToTypedSliceOverwrite(t *testing.T) { var out = []string{"qux"} - v := config.V([]config.Value{ - config.V("foo"), - config.V("bar"), + v := dyn.V([]dyn.Value{ + dyn.V("foo"), + dyn.V("bar"), }) err := ToTyped(&out, v) @@ -241,9 +241,9 @@ func TestToTypedSliceOverwrite(t *testing.T) { func TestToTypedSliceWithPointerElement(t *testing.T) { var out []*string - v := config.V([]config.Value{ - config.V("foo"), - config.V("bar"), + v := dyn.V([]dyn.Value{ + dyn.V("foo"), + dyn.V("bar"), }) err := ToTyped(&out, v) @@ -255,63 +255,63 @@ func TestToTypedSliceWithPointerElement(t *testing.T) { func TestToTypedSliceNil(t *testing.T) { var out []string - err := ToTyped(&out, config.NilValue) + err := ToTyped(&out, dyn.NilValue) require.NoError(t, err) assert.Nil(t, out) } func TestToTypedSliceNilOverwrite(t *testing.T) { var out = []string{"foo"} - err := ToTyped(&out, config.NilValue) + err := ToTyped(&out, dyn.NilValue) require.NoError(t, err) assert.Nil(t, out) } func TestToTypedString(t *testing.T) { var out string - err := ToTyped(&out, config.V("foo")) + err := ToTyped(&out, dyn.V("foo")) require.NoError(t, err) assert.Equal(t, "foo", out) } func TestToTypedStringOverwrite(t *testing.T) { var out string = "bar" - err := ToTyped(&out, config.V("foo")) + err := ToTyped(&out, dyn.V("foo")) require.NoError(t, err) assert.Equal(t, "foo", out) } func TestToTypedStringFromBool(t *testing.T) { var out string - err := ToTyped(&out, config.V(true)) + err := ToTyped(&out, dyn.V(true)) require.NoError(t, err) assert.Equal(t, "true", out) } func TestToTypedStringFromInt(t *testing.T) { var out string - err := ToTyped(&out, config.V(123)) + err := ToTyped(&out, dyn.V(123)) require.NoError(t, err) assert.Equal(t, "123", out) } func TestToTypedStringFromFloat(t *testing.T) { var out string - err := ToTyped(&out, config.V(1.2)) + err := ToTyped(&out, dyn.V(1.2)) require.NoError(t, err) assert.Equal(t, "1.2", out) } func TestToTypedBool(t *testing.T) { var out bool - err := ToTyped(&out, config.V(true)) + err := ToTyped(&out, dyn.V(true)) require.NoError(t, err) assert.Equal(t, true, out) } func TestToTypedBoolOverwrite(t *testing.T) { var out bool = true - err := ToTyped(&out, config.V(false)) + err := ToTyped(&out, dyn.V(false)) require.NoError(t, err) assert.Equal(t, false, out) } @@ -321,128 +321,128 @@ func TestToTypedBoolFromString(t *testing.T) { // True-ish for _, v := range []string{"y", "yes", "on"} { - err := ToTyped(&out, config.V(v)) + err := ToTyped(&out, dyn.V(v)) require.NoError(t, err) assert.Equal(t, true, out) } // False-ish for _, v := range []string{"n", "no", "off"} { - err := ToTyped(&out, config.V(v)) + err := ToTyped(&out, dyn.V(v)) require.NoError(t, err) assert.Equal(t, false, out) } // Other - err := ToTyped(&out, config.V("${var.foo}")) + err := ToTyped(&out, dyn.V("${var.foo}")) require.Error(t, err) } func TestToTypedInt(t *testing.T) { var out int - err := ToTyped(&out, config.V(1234)) + err := ToTyped(&out, dyn.V(1234)) require.NoError(t, err) assert.Equal(t, int(1234), out) } func TestToTypedInt32(t *testing.T) { var out32 int32 - err := ToTyped(&out32, config.V(1235)) + err := ToTyped(&out32, dyn.V(1235)) require.NoError(t, err) assert.Equal(t, int32(1235), out32) } func TestToTypedInt64(t *testing.T) { var out64 int64 - err := ToTyped(&out64, config.V(1236)) + err := ToTyped(&out64, dyn.V(1236)) require.NoError(t, err) assert.Equal(t, int64(1236), out64) } func TestToTypedIntOverwrite(t *testing.T) { var out int = 123 - err := ToTyped(&out, config.V(1234)) + err := ToTyped(&out, dyn.V(1234)) require.NoError(t, err) assert.Equal(t, int(1234), out) } func TestToTypedInt32Overwrite(t *testing.T) { var out32 int32 = 123 - err := ToTyped(&out32, config.V(1234)) + err := ToTyped(&out32, dyn.V(1234)) require.NoError(t, err) assert.Equal(t, int32(1234), out32) } func TestToTypedInt64Overwrite(t *testing.T) { var out64 int64 = 123 - err := ToTyped(&out64, config.V(1234)) + err := ToTyped(&out64, dyn.V(1234)) require.NoError(t, err) assert.Equal(t, int64(1234), out64) } func TestToTypedIntFromStringError(t *testing.T) { var out int - err := ToTyped(&out, config.V("abc")) + err := ToTyped(&out, dyn.V("abc")) require.Error(t, err) } func TestToTypedIntFromStringInt(t *testing.T) { var out int - err := ToTyped(&out, config.V("123")) + err := ToTyped(&out, dyn.V("123")) require.NoError(t, err) assert.Equal(t, int(123), out) } func TestToTypedFloat32(t *testing.T) { var out float32 - err := ToTyped(&out, config.V(float32(1.0))) + err := ToTyped(&out, dyn.V(float32(1.0))) require.NoError(t, err) assert.Equal(t, float32(1.0), out) } func TestToTypedFloat64(t *testing.T) { var out float64 - err := ToTyped(&out, config.V(float64(1.0))) + err := ToTyped(&out, dyn.V(float64(1.0))) require.NoError(t, err) assert.Equal(t, float64(1.0), out) } func TestToTypedFloat32Overwrite(t *testing.T) { var out float32 = 1.0 - err := ToTyped(&out, config.V(float32(2.0))) + err := ToTyped(&out, dyn.V(float32(2.0))) require.NoError(t, err) assert.Equal(t, float32(2.0), out) } func TestToTypedFloat64Overwrite(t *testing.T) { var out float64 = 1.0 - err := ToTyped(&out, config.V(float64(2.0))) + err := ToTyped(&out, dyn.V(float64(2.0))) require.NoError(t, err) assert.Equal(t, float64(2.0), out) } func TestToTypedFloat32FromStringError(t *testing.T) { var out float32 - err := ToTyped(&out, config.V("abc")) + err := ToTyped(&out, dyn.V("abc")) require.Error(t, err) } func TestToTypedFloat64FromStringError(t *testing.T) { var out float64 - err := ToTyped(&out, config.V("abc")) + err := ToTyped(&out, dyn.V("abc")) require.Error(t, err) } func TestToTypedFloat32FromString(t *testing.T) { var out float32 - err := ToTyped(&out, config.V("1.2")) + err := ToTyped(&out, dyn.V("1.2")) require.NoError(t, err) assert.Equal(t, float32(1.2), out) } func TestToTypedFloat64FromString(t *testing.T) { var out float64 - err := ToTyped(&out, config.V("1.2")) + err := ToTyped(&out, dyn.V("1.2")) require.NoError(t, err) assert.Equal(t, float64(1.2), out) } diff --git a/libs/config/kind.go b/libs/dyn/kind.go similarity index 98% rename from libs/config/kind.go rename to libs/dyn/kind.go index 5ed1a665..ba093341 100644 --- a/libs/config/kind.go +++ b/libs/dyn/kind.go @@ -1,4 +1,4 @@ -package config +package dyn import "time" diff --git a/libs/config/location.go b/libs/dyn/location.go similarity index 92% rename from libs/config/location.go rename to libs/dyn/location.go index 534b21c2..cd369193 100644 --- a/libs/config/location.go +++ b/libs/dyn/location.go @@ -1,4 +1,4 @@ -package config +package dyn import "fmt" diff --git a/libs/config/location_test.go b/libs/dyn/location_test.go similarity index 54% rename from libs/config/location_test.go rename to libs/dyn/location_test.go index 31013193..29226d73 100644 --- a/libs/config/location_test.go +++ b/libs/dyn/location_test.go @@ -1,13 +1,13 @@ -package config_test +package dyn_test import ( "testing" - "github.com/databricks/cli/libs/config" + "github.com/databricks/cli/libs/dyn" "github.com/stretchr/testify/assert" ) func TestLocation(t *testing.T) { - loc := config.Location{File: "file", Line: 1, Column: 2} + loc := dyn.Location{File: "file", Line: 1, Column: 2} assert.Equal(t, "file:1:2", loc.String()) } diff --git a/libs/config/merge/merge.go b/libs/dyn/merge/merge.go similarity index 60% rename from libs/config/merge/merge.go rename to libs/dyn/merge/merge.go index 896e2129..1cadbea6 100644 --- a/libs/config/merge/merge.go +++ b/libs/dyn/merge/merge.go @@ -3,7 +3,7 @@ package merge import ( "fmt" - "github.com/databricks/cli/libs/config" + "github.com/databricks/cli/libs/dyn" ) // Merge recursively merges the specified values. @@ -12,46 +12,46 @@ import ( // * Merging x with nil or nil with x always yields x. // * Merging maps a and b means entries from map b take precedence. // * Merging sequences a and b means concatenating them. -func Merge(a, b config.Value) (config.Value, error) { +func Merge(a, b dyn.Value) (dyn.Value, error) { return merge(a, b) } -func merge(a, b config.Value) (config.Value, error) { +func merge(a, b dyn.Value) (dyn.Value, error) { ak := a.Kind() bk := b.Kind() // If a is nil, return b. - if ak == config.KindNil { + if ak == dyn.KindNil { return b, nil } // If b is nil, return a. - if bk == config.KindNil { + if bk == dyn.KindNil { return a, nil } // Call the appropriate merge function based on the kind of a and b. switch ak { - case config.KindMap: - if bk != config.KindMap { - return config.NilValue, fmt.Errorf("cannot merge map with %s", bk) + case dyn.KindMap: + if bk != dyn.KindMap { + return dyn.NilValue, fmt.Errorf("cannot merge map with %s", bk) } return mergeMap(a, b) - case config.KindSequence: - if bk != config.KindSequence { - return config.NilValue, fmt.Errorf("cannot merge sequence with %s", bk) + case dyn.KindSequence: + if bk != dyn.KindSequence { + return dyn.NilValue, fmt.Errorf("cannot merge sequence with %s", bk) } return mergeSequence(a, b) default: if ak != bk { - return config.NilValue, fmt.Errorf("cannot merge %s with %s", ak, bk) + return dyn.NilValue, fmt.Errorf("cannot merge %s with %s", ak, bk) } return mergePrimitive(a, b) } } -func mergeMap(a, b config.Value) (config.Value, error) { - out := make(map[string]config.Value) +func mergeMap(a, b dyn.Value) (dyn.Value, error) { + out := make(map[string]dyn.Value) am := a.MustMap() bm := b.MustMap() @@ -66,7 +66,7 @@ func mergeMap(a, b config.Value) (config.Value, error) { // If the key already exists, merge the values. merged, err := merge(out[k], v) if err != nil { - return config.NilValue, err + return dyn.NilValue, err } out[k] = merged } else { @@ -76,23 +76,23 @@ func mergeMap(a, b config.Value) (config.Value, error) { } // Preserve the location of the first value. - return config.NewValue(out, a.Location()), nil + return dyn.NewValue(out, a.Location()), nil } -func mergeSequence(a, b config.Value) (config.Value, error) { +func mergeSequence(a, b dyn.Value) (dyn.Value, error) { as := a.MustSequence() bs := b.MustSequence() // Merging sequences means concatenating them. - out := make([]config.Value, len(as)+len(bs)) + out := make([]dyn.Value, len(as)+len(bs)) copy(out[:], as) copy(out[len(as):], bs) // Preserve the location of the first value. - return config.NewValue(out, a.Location()), nil + return dyn.NewValue(out, a.Location()), nil } -func mergePrimitive(a, b config.Value) (config.Value, error) { +func mergePrimitive(a, b dyn.Value) (dyn.Value, error) { // Merging primitive values means using the incoming value. return b, nil } diff --git a/libs/config/merge/merge_test.go b/libs/dyn/merge/merge_test.go similarity index 67% rename from libs/config/merge/merge_test.go rename to libs/dyn/merge/merge_test.go index c2e89f60..c4928e35 100644 --- a/libs/config/merge/merge_test.go +++ b/libs/dyn/merge/merge_test.go @@ -3,19 +3,19 @@ package merge import ( "testing" - "github.com/databricks/cli/libs/config" + "github.com/databricks/cli/libs/dyn" "github.com/stretchr/testify/assert" ) func TestMergeMaps(t *testing.T) { - v1 := config.V(map[string]config.Value{ - "foo": config.V("bar"), - "bar": config.V("baz"), + v1 := dyn.V(map[string]dyn.Value{ + "foo": dyn.V("bar"), + "bar": dyn.V("baz"), }) - v2 := config.V(map[string]config.Value{ - "bar": config.V("qux"), - "qux": config.V("foo"), + v2 := dyn.V(map[string]dyn.Value{ + "bar": dyn.V("qux"), + "qux": dyn.V("foo"), }) // Merge v2 into v1. @@ -42,13 +42,13 @@ func TestMergeMaps(t *testing.T) { } func TestMergeMapsNil(t *testing.T) { - v := config.V(map[string]config.Value{ - "foo": config.V("bar"), + v := dyn.V(map[string]dyn.Value{ + "foo": dyn.V("bar"), }) // Merge nil into v. { - out, err := Merge(v, config.NilValue) + out, err := Merge(v, dyn.NilValue) assert.NoError(t, err) assert.Equal(t, map[string]any{ "foo": "bar", @@ -57,7 +57,7 @@ func TestMergeMapsNil(t *testing.T) { // Merge v into nil. { - out, err := Merge(config.NilValue, v) + out, err := Merge(dyn.NilValue, v) assert.NoError(t, err) assert.Equal(t, map[string]any{ "foo": "bar", @@ -66,29 +66,29 @@ func TestMergeMapsNil(t *testing.T) { } func TestMergeMapsError(t *testing.T) { - v := config.V(map[string]config.Value{ - "foo": config.V("bar"), + v := dyn.V(map[string]dyn.Value{ + "foo": dyn.V("bar"), }) - other := config.V("string") + other := dyn.V("string") // Merge a string into v. { out, err := Merge(v, other) assert.EqualError(t, err, "cannot merge map with string") - assert.Equal(t, config.NilValue, out) + assert.Equal(t, dyn.NilValue, out) } } func TestMergeSequences(t *testing.T) { - v1 := config.V([]config.Value{ - config.V("bar"), - config.V("baz"), + v1 := dyn.V([]dyn.Value{ + dyn.V("bar"), + dyn.V("baz"), }) - v2 := config.V([]config.Value{ - config.V("qux"), - config.V("foo"), + v2 := dyn.V([]dyn.Value{ + dyn.V("qux"), + dyn.V("foo"), }) // Merge v2 into v1. @@ -117,13 +117,13 @@ func TestMergeSequences(t *testing.T) { } func TestMergeSequencesNil(t *testing.T) { - v := config.V([]config.Value{ - config.V("bar"), + v := dyn.V([]dyn.Value{ + dyn.V("bar"), }) // Merge nil into v. { - out, err := Merge(v, config.NilValue) + out, err := Merge(v, dyn.NilValue) assert.NoError(t, err) assert.Equal(t, []any{ "bar", @@ -132,7 +132,7 @@ func TestMergeSequencesNil(t *testing.T) { // Merge v into nil. { - out, err := Merge(config.NilValue, v) + out, err := Merge(dyn.NilValue, v) assert.NoError(t, err) assert.Equal(t, []any{ "bar", @@ -141,23 +141,23 @@ func TestMergeSequencesNil(t *testing.T) { } func TestMergeSequencesError(t *testing.T) { - v := config.V([]config.Value{ - config.V("bar"), + v := dyn.V([]dyn.Value{ + dyn.V("bar"), }) - other := config.V("string") + other := dyn.V("string") // Merge a string into v. { out, err := Merge(v, other) assert.EqualError(t, err, "cannot merge sequence with string") - assert.Equal(t, config.NilValue, out) + assert.Equal(t, dyn.NilValue, out) } } func TestMergePrimitives(t *testing.T) { - v1 := config.V("bar") - v2 := config.V("baz") + v1 := dyn.V("bar") + v2 := dyn.V("baz") // Merge v2 into v1. { @@ -175,33 +175,33 @@ func TestMergePrimitives(t *testing.T) { } func TestMergePrimitivesNil(t *testing.T) { - v := config.V("bar") + v := dyn.V("bar") // Merge nil into v. { - out, err := Merge(v, config.NilValue) + out, err := Merge(v, dyn.NilValue) assert.NoError(t, err) assert.Equal(t, "bar", out.AsAny()) } // Merge v into nil. { - out, err := Merge(config.NilValue, v) + out, err := Merge(dyn.NilValue, v) assert.NoError(t, err) assert.Equal(t, "bar", out.AsAny()) } } func TestMergePrimitivesError(t *testing.T) { - v := config.V("bar") - other := config.V(map[string]config.Value{ - "foo": config.V("bar"), + v := dyn.V("bar") + other := dyn.V(map[string]dyn.Value{ + "foo": dyn.V("bar"), }) // Merge a map into v. { out, err := Merge(v, other) assert.EqualError(t, err, "cannot merge string with map") - assert.Equal(t, config.NilValue, out) + assert.Equal(t, dyn.NilValue, out) } } diff --git a/libs/config/path.go b/libs/dyn/path.go similarity index 99% rename from libs/config/path.go rename to libs/dyn/path.go index f1abf48c..bfd93dad 100644 --- a/libs/config/path.go +++ b/libs/dyn/path.go @@ -1,4 +1,4 @@ -package config +package dyn import ( "bytes" diff --git a/libs/config/path_string.go b/libs/dyn/path_string.go similarity index 99% rename from libs/config/path_string.go rename to libs/dyn/path_string.go index 9538ad27..0fa0c682 100644 --- a/libs/config/path_string.go +++ b/libs/dyn/path_string.go @@ -1,4 +1,4 @@ -package config +package dyn import ( "fmt" diff --git a/libs/config/path_string_test.go b/libs/dyn/path_string_test.go similarity index 96% rename from libs/config/path_string_test.go rename to libs/dyn/path_string_test.go index 89e64561..9af394c6 100644 --- a/libs/config/path_string_test.go +++ b/libs/dyn/path_string_test.go @@ -1,10 +1,10 @@ -package config_test +package dyn_test import ( "fmt" "testing" - . "github.com/databricks/cli/libs/config" + . "github.com/databricks/cli/libs/dyn" "github.com/stretchr/testify/assert" ) diff --git a/libs/dyn/path_test.go b/libs/dyn/path_test.go new file mode 100644 index 00000000..c4ea26c4 --- /dev/null +++ b/libs/dyn/path_test.go @@ -0,0 +1,76 @@ +package dyn_test + +import ( + "testing" + + "github.com/databricks/cli/libs/dyn" + "github.com/stretchr/testify/assert" +) + +func TestPathAppend(t *testing.T) { + p := dyn.NewPath(dyn.Key("foo")) + + // Single arg. + p1 := p.Append(dyn.Key("bar")) + assert.True(t, p1.Equal(dyn.NewPath(dyn.Key("foo"), dyn.Key("bar")))) + + // Multiple args. + p2 := p.Append(dyn.Key("bar"), dyn.Index(1)) + assert.True(t, p2.Equal(dyn.NewPath(dyn.Key("foo"), dyn.Key("bar"), dyn.Index(1)))) +} + +func TestPathJoin(t *testing.T) { + p := dyn.NewPath(dyn.Key("foo")) + + // Single arg. + p1 := p.Join(dyn.NewPath(dyn.Key("bar"))) + assert.True(t, p1.Equal(dyn.NewPath(dyn.Key("foo"), dyn.Key("bar")))) + + // Multiple args. + p2 := p.Join(dyn.NewPath(dyn.Key("bar")), dyn.NewPath(dyn.Index(1))) + assert.True(t, p2.Equal(dyn.NewPath(dyn.Key("foo"), dyn.Key("bar"), dyn.Index(1)))) +} + +func TestPathEqualEmpty(t *testing.T) { + assert.True(t, dyn.EmptyPath.Equal(dyn.EmptyPath)) +} + +func TestPathEqual(t *testing.T) { + p1 := dyn.NewPath(dyn.Key("foo"), dyn.Index(1)) + p2 := dyn.NewPath(dyn.Key("bar"), dyn.Index(2)) + assert.False(t, p1.Equal(p2), "expected %q to not equal %q", p1, p2) + + p3 := dyn.NewPath(dyn.Key("foo"), dyn.Index(1)) + assert.True(t, p1.Equal(p3), "expected %q to equal %q", p1, p3) + + p4 := dyn.NewPath(dyn.Key("foo"), dyn.Index(1), dyn.Key("bar"), dyn.Index(2)) + assert.False(t, p1.Equal(p4), "expected %q to not equal %q", p1, p4) +} + +func TestPathHasPrefixEmpty(t *testing.T) { + empty := dyn.EmptyPath + nonEmpty := dyn.NewPath(dyn.Key("foo")) + assert.True(t, empty.HasPrefix(empty)) + assert.True(t, nonEmpty.HasPrefix(empty)) + assert.False(t, empty.HasPrefix(nonEmpty)) +} + +func TestPathHasPrefix(t *testing.T) { + p1 := dyn.NewPath(dyn.Key("foo"), dyn.Index(1)) + p2 := dyn.NewPath(dyn.Key("bar"), dyn.Index(2)) + assert.False(t, p1.HasPrefix(p2), "expected %q to not have prefix %q", p1, p2) + + p3 := dyn.NewPath(dyn.Key("foo")) + assert.True(t, p1.HasPrefix(p3), "expected %q to have prefix %q", p1, p3) +} + +func TestPathString(t *testing.T) { + p1 := dyn.NewPath(dyn.Key("foo"), dyn.Index(1)) + assert.Equal(t, "foo[1]", p1.String()) + + p2 := dyn.NewPath(dyn.Key("bar"), dyn.Index(2), dyn.Key("baz")) + assert.Equal(t, "bar[2].baz", p2.String()) + + p3 := dyn.NewPath(dyn.Key("foo"), dyn.Index(1), dyn.Key("bar"), dyn.Index(2), dyn.Key("baz")) + assert.Equal(t, "foo[1].bar[2].baz", p3.String()) +} diff --git a/libs/config/value.go b/libs/dyn/value.go similarity index 99% rename from libs/config/value.go rename to libs/dyn/value.go index fe0ced9b..9ac738f9 100644 --- a/libs/config/value.go +++ b/libs/dyn/value.go @@ -1,4 +1,4 @@ -package config +package dyn import ( "fmt" diff --git a/libs/config/value_test.go b/libs/dyn/value_test.go similarity index 55% rename from libs/config/value_test.go rename to libs/dyn/value_test.go index 6c8befc7..5fa45f15 100644 --- a/libs/config/value_test.go +++ b/libs/dyn/value_test.go @@ -1,35 +1,35 @@ -package config_test +package dyn_test import ( "testing" - "github.com/databricks/cli/libs/config" + "github.com/databricks/cli/libs/dyn" "github.com/stretchr/testify/assert" ) func TestValueIsAnchor(t *testing.T) { - var zero config.Value + var zero dyn.Value assert.False(t, zero.IsAnchor()) mark := zero.MarkAnchor() assert.True(t, mark.IsAnchor()) } func TestValueAsMap(t *testing.T) { - var zeroValue config.Value + var zeroValue dyn.Value m, ok := zeroValue.AsMap() assert.False(t, ok) assert.Nil(t, m) - var intValue = config.NewValue(1, config.Location{}) + var intValue = dyn.NewValue(1, dyn.Location{}) m, ok = intValue.AsMap() assert.False(t, ok) assert.Nil(t, m) - var mapValue = config.NewValue( - map[string]config.Value{ - "key": config.NewValue("value", config.Location{File: "file", Line: 1, Column: 2}), + var mapValue = dyn.NewValue( + map[string]dyn.Value{ + "key": dyn.NewValue("value", dyn.Location{File: "file", Line: 1, Column: 2}), }, - config.Location{File: "file", Line: 1, Column: 2}, + dyn.Location{File: "file", Line: 1, Column: 2}, ) m, ok = mapValue.AsMap() assert.True(t, ok) @@ -37,8 +37,8 @@ func TestValueAsMap(t *testing.T) { } func TestValueIsValid(t *testing.T) { - var zeroValue config.Value + var zeroValue dyn.Value assert.False(t, zeroValue.IsValid()) - var intValue = config.NewValue(1, config.Location{}) + var intValue = dyn.NewValue(1, dyn.Location{}) assert.True(t, intValue.IsValid()) } diff --git a/libs/config/walk.go b/libs/dyn/walk.go similarity index 99% rename from libs/config/walk.go rename to libs/dyn/walk.go index ce058338..138816be 100644 --- a/libs/config/walk.go +++ b/libs/dyn/walk.go @@ -1,4 +1,4 @@ -package config +package dyn import "errors" diff --git a/libs/config/walk_test.go b/libs/dyn/walk_test.go similarity index 98% rename from libs/config/walk_test.go rename to libs/dyn/walk_test.go index 806ca256..1b94ad90 100644 --- a/libs/config/walk_test.go +++ b/libs/dyn/walk_test.go @@ -1,10 +1,10 @@ -package config_test +package dyn_test import ( "errors" "testing" - . "github.com/databricks/cli/libs/config" + . "github.com/databricks/cli/libs/dyn" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/libs/config/yamlloader/loader.go b/libs/dyn/yamlloader/loader.go similarity index 61% rename from libs/config/yamlloader/loader.go rename to libs/dyn/yamlloader/loader.go index 6472c137..899e1d7b 100644 --- a/libs/config/yamlloader/loader.go +++ b/libs/dyn/yamlloader/loader.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/databricks/cli/libs/config" + "github.com/databricks/cli/libs/dyn" "gopkg.in/yaml.v3" ) @@ -15,7 +15,7 @@ type loader struct { path string } -func errorf(loc config.Location, format string, args ...interface{}) error { +func errorf(loc dyn.Location, format string, args ...interface{}) error { return fmt.Errorf("yaml (%s): %s", loc, fmt.Sprintf(format, args...)) } @@ -25,22 +25,22 @@ func newLoader(path string) *loader { } } -func (d *loader) location(node *yaml.Node) config.Location { - return config.Location{ +func (d *loader) location(node *yaml.Node) dyn.Location { + return dyn.Location{ File: d.path, Line: node.Line, Column: node.Column, } } -func (d *loader) load(node *yaml.Node) (config.Value, error) { - loc := config.Location{ +func (d *loader) load(node *yaml.Node) (dyn.Value, error) { + loc := dyn.Location{ File: d.path, Line: node.Line, Column: node.Column, } - var value config.Value + var value dyn.Value var err error switch node.Kind { @@ -55,7 +55,7 @@ func (d *loader) load(node *yaml.Node) (config.Value, error) { case yaml.AliasNode: value, err = d.loadAlias(node, loc) default: - return config.NilValue, errorf(loc, "unknown node kind: %v", node.Kind) + return dyn.NilValue, errorf(loc, "unknown node kind: %v", node.Kind) } if err != nil { @@ -71,35 +71,35 @@ func (d *loader) load(node *yaml.Node) (config.Value, error) { return value, nil } -func (d *loader) loadDocument(node *yaml.Node, loc config.Location) (config.Value, error) { +func (d *loader) loadDocument(node *yaml.Node, loc dyn.Location) (dyn.Value, error) { return d.load(node.Content[0]) } -func (d *loader) loadSequence(node *yaml.Node, loc config.Location) (config.Value, error) { - acc := make([]config.Value, len(node.Content)) +func (d *loader) loadSequence(node *yaml.Node, loc dyn.Location) (dyn.Value, error) { + acc := make([]dyn.Value, len(node.Content)) for i, n := range node.Content { v, err := d.load(n) if err != nil { - return config.NilValue, err + return dyn.NilValue, err } acc[i] = v } - return config.NewValue(acc, loc), nil + return dyn.NewValue(acc, loc), nil } -func (d *loader) loadMapping(node *yaml.Node, loc config.Location) (config.Value, error) { +func (d *loader) loadMapping(node *yaml.Node, loc dyn.Location) (dyn.Value, error) { var merge *yaml.Node - acc := make(map[string]config.Value) + acc := make(map[string]dyn.Value) for i := 0; i < len(node.Content); i += 2 { key := node.Content[i] val := node.Content[i+1] // Assert that keys are strings if key.Kind != yaml.ScalarNode { - return config.NilValue, errorf(loc, "key is not a scalar") + return dyn.NilValue, errorf(loc, "key is not a scalar") } st := key.ShortTag() @@ -113,19 +113,19 @@ func (d *loader) loadMapping(node *yaml.Node, loc config.Location) (config.Value merge = val continue default: - return config.NilValue, errorf(loc, "invalid key tag: %v", st) + return dyn.NilValue, errorf(loc, "invalid key tag: %v", st) } v, err := d.load(val) if err != nil { - return config.NilValue, err + return dyn.NilValue, err } acc[key.Value] = v } if merge == nil { - return config.NewValue(acc, loc), nil + return dyn.NewValue(acc, loc), nil } // Build location for the merge node. @@ -141,68 +141,68 @@ func (d *loader) loadMapping(node *yaml.Node, loc config.Location) (config.Value case yaml.AliasNode: mnodes = []*yaml.Node{merge} default: - return config.NilValue, merr + return dyn.NilValue, merr } // Build a sequence of values to merge. // The entries that we already accumulated have precedence. - var seq []map[string]config.Value + var seq []map[string]dyn.Value for _, n := range mnodes { v, err := d.load(n) if err != nil { - return config.NilValue, err + return dyn.NilValue, err } m, ok := v.AsMap() if !ok { - return config.NilValue, merr + return dyn.NilValue, merr } seq = append(seq, m) } // Append the accumulated entries to the sequence. seq = append(seq, acc) - out := make(map[string]config.Value) + out := make(map[string]dyn.Value) for _, m := range seq { for k, v := range m { out[k] = v } } - return config.NewValue(out, loc), nil + return dyn.NewValue(out, loc), nil } -func (d *loader) loadScalar(node *yaml.Node, loc config.Location) (config.Value, error) { +func (d *loader) loadScalar(node *yaml.Node, loc dyn.Location) (dyn.Value, error) { st := node.ShortTag() switch st { case "!!str": - return config.NewValue(node.Value, loc), nil + return dyn.NewValue(node.Value, loc), nil case "!!bool": switch strings.ToLower(node.Value) { case "true": - return config.NewValue(true, loc), nil + return dyn.NewValue(true, loc), nil case "false": - return config.NewValue(false, loc), nil + return dyn.NewValue(false, loc), nil default: - return config.NilValue, errorf(loc, "invalid bool value: %v", node.Value) + return dyn.NilValue, errorf(loc, "invalid bool value: %v", node.Value) } case "!!int": i64, err := strconv.ParseInt(node.Value, 10, 64) if err != nil { - return config.NilValue, errorf(loc, "invalid int value: %v", node.Value) + return dyn.NilValue, errorf(loc, "invalid int value: %v", node.Value) } // Use regular int type instead of int64 if possible. if i64 >= math.MinInt32 && i64 <= math.MaxInt32 { - return config.NewValue(int(i64), loc), nil + return dyn.NewValue(int(i64), loc), nil } - return config.NewValue(i64, loc), nil + return dyn.NewValue(i64, loc), nil case "!!float": f64, err := strconv.ParseFloat(node.Value, 64) if err != nil { - return config.NilValue, errorf(loc, "invalid float value: %v", node.Value) + return dyn.NilValue, errorf(loc, "invalid float value: %v", node.Value) } - return config.NewValue(f64, loc), nil + return dyn.NewValue(f64, loc), nil case "!!null": - return config.NewValue(nil, loc), nil + return dyn.NewValue(nil, loc), nil case "!!timestamp": // Try a couple of layouts for _, layout := range []string{ @@ -213,15 +213,15 @@ func (d *loader) loadScalar(node *yaml.Node, loc config.Location) (config.Value, } { t, terr := time.Parse(layout, node.Value) if terr == nil { - return config.NewValue(t, loc), nil + return dyn.NewValue(t, loc), nil } } - return config.NilValue, errorf(loc, "invalid timestamp value: %v", node.Value) + return dyn.NilValue, errorf(loc, "invalid timestamp value: %v", node.Value) default: - return config.NilValue, errorf(loc, "unknown tag: %v", st) + return dyn.NilValue, errorf(loc, "unknown tag: %v", st) } } -func (d *loader) loadAlias(node *yaml.Node, loc config.Location) (config.Value, error) { +func (d *loader) loadAlias(node *yaml.Node, loc dyn.Location) (dyn.Value, error) { return d.load(node.Alias) } diff --git a/libs/config/yamlloader/testdata/anchor_01.yml b/libs/dyn/yamlloader/testdata/anchor_01.yml similarity index 100% rename from libs/config/yamlloader/testdata/anchor_01.yml rename to libs/dyn/yamlloader/testdata/anchor_01.yml diff --git a/libs/config/yamlloader/testdata/anchor_02.yml b/libs/dyn/yamlloader/testdata/anchor_02.yml similarity index 100% rename from libs/config/yamlloader/testdata/anchor_02.yml rename to libs/dyn/yamlloader/testdata/anchor_02.yml diff --git a/libs/config/yamlloader/testdata/anchor_03.yml b/libs/dyn/yamlloader/testdata/anchor_03.yml similarity index 100% rename from libs/config/yamlloader/testdata/anchor_03.yml rename to libs/dyn/yamlloader/testdata/anchor_03.yml diff --git a/libs/config/yamlloader/testdata/anchor_04.yml b/libs/dyn/yamlloader/testdata/anchor_04.yml similarity index 100% rename from libs/config/yamlloader/testdata/anchor_04.yml rename to libs/dyn/yamlloader/testdata/anchor_04.yml diff --git a/libs/config/yamlloader/testdata/anchor_05.yml b/libs/dyn/yamlloader/testdata/anchor_05.yml similarity index 100% rename from libs/config/yamlloader/testdata/anchor_05.yml rename to libs/dyn/yamlloader/testdata/anchor_05.yml diff --git a/libs/config/yamlloader/testdata/anchor_06.yml b/libs/dyn/yamlloader/testdata/anchor_06.yml similarity index 100% rename from libs/config/yamlloader/testdata/anchor_06.yml rename to libs/dyn/yamlloader/testdata/anchor_06.yml diff --git a/libs/config/yamlloader/testdata/anchor_07.yml b/libs/dyn/yamlloader/testdata/anchor_07.yml similarity index 100% rename from libs/config/yamlloader/testdata/anchor_07.yml rename to libs/dyn/yamlloader/testdata/anchor_07.yml diff --git a/libs/config/yamlloader/testdata/anchor_08.yml b/libs/dyn/yamlloader/testdata/anchor_08.yml similarity index 100% rename from libs/config/yamlloader/testdata/anchor_08.yml rename to libs/dyn/yamlloader/testdata/anchor_08.yml diff --git a/libs/config/yamlloader/testdata/empty.yml b/libs/dyn/yamlloader/testdata/empty.yml similarity index 100% rename from libs/config/yamlloader/testdata/empty.yml rename to libs/dyn/yamlloader/testdata/empty.yml diff --git a/libs/config/yamlloader/testdata/error_01.yml b/libs/dyn/yamlloader/testdata/error_01.yml similarity index 100% rename from libs/config/yamlloader/testdata/error_01.yml rename to libs/dyn/yamlloader/testdata/error_01.yml diff --git a/libs/config/yamlloader/testdata/error_02.yml b/libs/dyn/yamlloader/testdata/error_02.yml similarity index 100% rename from libs/config/yamlloader/testdata/error_02.yml rename to libs/dyn/yamlloader/testdata/error_02.yml diff --git a/libs/config/yamlloader/testdata/error_03.yml b/libs/dyn/yamlloader/testdata/error_03.yml similarity index 100% rename from libs/config/yamlloader/testdata/error_03.yml rename to libs/dyn/yamlloader/testdata/error_03.yml diff --git a/libs/config/yamlloader/testdata/mix_01.yml b/libs/dyn/yamlloader/testdata/mix_01.yml similarity index 100% rename from libs/config/yamlloader/testdata/mix_01.yml rename to libs/dyn/yamlloader/testdata/mix_01.yml diff --git a/libs/config/yamlloader/testdata/mix_02.yml b/libs/dyn/yamlloader/testdata/mix_02.yml similarity index 100% rename from libs/config/yamlloader/testdata/mix_02.yml rename to libs/dyn/yamlloader/testdata/mix_02.yml diff --git a/libs/config/yamlloader/yaml.go b/libs/dyn/yamlloader/yaml.go similarity index 56% rename from libs/config/yamlloader/yaml.go rename to libs/dyn/yamlloader/yaml.go index a3cc7284..a18324ff 100644 --- a/libs/config/yamlloader/yaml.go +++ b/libs/dyn/yamlloader/yaml.go @@ -3,19 +3,19 @@ package yamlloader import ( "io" - "github.com/databricks/cli/libs/config" + "github.com/databricks/cli/libs/dyn" "gopkg.in/yaml.v3" ) -func LoadYAML(path string, r io.Reader) (config.Value, error) { +func LoadYAML(path string, r io.Reader) (dyn.Value, error) { var node yaml.Node dec := yaml.NewDecoder(r) err := dec.Decode(&node) if err != nil { if err == io.EOF { - return config.NilValue, nil + return dyn.NilValue, nil } - return config.NilValue, err + return dyn.NilValue, err } return newLoader(path).load(&node) diff --git a/libs/config/yamlloader/yaml_anchor_test.go b/libs/dyn/yamlloader/yaml_anchor_test.go similarity index 61% rename from libs/config/yamlloader/yaml_anchor_test.go rename to libs/dyn/yamlloader/yaml_anchor_test.go index a8b66686..05beb540 100644 --- a/libs/config/yamlloader/yaml_anchor_test.go +++ b/libs/dyn/yamlloader/yaml_anchor_test.go @@ -3,14 +3,14 @@ package yamlloader_test import ( "testing" - "github.com/databricks/cli/libs/config" + "github.com/databricks/cli/libs/dyn" "github.com/stretchr/testify/assert" ) func TestYAMLAnchor01(t *testing.T) { file := "testdata/anchor_01.yml" self := loadYAML(t, file) - assert.NotEqual(t, config.NilValue, self) + assert.NotEqual(t, dyn.NilValue, self) assert.True(t, self.Get("defaults").IsAnchor()) assert.False(t, self.Get("shirt1").IsAnchor()) @@ -18,31 +18,31 @@ func TestYAMLAnchor01(t *testing.T) { pattern := self.Get("shirt1").Get("pattern") assert.Equal(t, "striped", pattern.AsAny()) - assert.Equal(t, config.Location{File: file, Line: 8, Column: 12}, pattern.Location()) + assert.Equal(t, dyn.Location{File: file, Line: 8, Column: 12}, pattern.Location()) } func TestYAMLAnchor02(t *testing.T) { file := "testdata/anchor_02.yml" self := loadYAML(t, file) - assert.NotEqual(t, config.NilValue, self) + assert.NotEqual(t, dyn.NilValue, self) color := self.Get("shirt").Get("color") assert.Equal(t, "red", color.AsAny()) - assert.Equal(t, config.Location{File: file, Line: 4, Column: 10}, color.Location()) + assert.Equal(t, dyn.Location{File: file, Line: 4, Column: 10}, color.Location()) primary := self.Get("shirt").Get("primary") assert.Equal(t, "cotton", primary.AsAny()) - assert.Equal(t, config.Location{File: file, Line: 8, Column: 12}, primary.Location()) + assert.Equal(t, dyn.Location{File: file, Line: 8, Column: 12}, primary.Location()) pattern := self.Get("shirt").Get("pattern") assert.Equal(t, "striped", pattern.AsAny()) - assert.Equal(t, config.Location{File: file, Line: 13, Column: 12}, pattern.Location()) + assert.Equal(t, dyn.Location{File: file, Line: 13, Column: 12}, pattern.Location()) } func TestYAMLAnchor03(t *testing.T) { file := "testdata/anchor_03.yml" self := loadYAML(t, file) - assert.NotEqual(t, config.NilValue, self) + assert.NotEqual(t, dyn.NilValue, self) // Assert the override took place. blue := self.Get("shirt").Get("color") @@ -55,63 +55,63 @@ func TestYAMLAnchor03(t *testing.T) { func TestYAMLAnchor04(t *testing.T) { file := "testdata/anchor_04.yml" self := loadYAML(t, file) - assert.NotEqual(t, config.NilValue, self) + assert.NotEqual(t, dyn.NilValue, self) p1 := self.Get("person1").Get("address").Get("city") assert.Equal(t, "San Francisco", p1.AsAny()) - assert.Equal(t, config.Location{File: file, Line: 4, Column: 9}, p1.Location()) + assert.Equal(t, dyn.Location{File: file, Line: 4, Column: 9}, p1.Location()) p2 := self.Get("person2").Get("address").Get("city") assert.Equal(t, "Los Angeles", p2.AsAny()) - assert.Equal(t, config.Location{File: file, Line: 16, Column: 11}, p2.Location()) + assert.Equal(t, dyn.Location{File: file, Line: 16, Column: 11}, p2.Location()) } func TestYAMLAnchor05(t *testing.T) { file := "testdata/anchor_05.yml" self := loadYAML(t, file) - assert.NotEqual(t, config.NilValue, self) + assert.NotEqual(t, dyn.NilValue, self) features := self.Get("phone1").Get("features") assert.Equal(t, "wifi", features.Index(0).AsAny()) - assert.Equal(t, config.Location{File: file, Line: 4, Column: 5}, features.Index(0).Location()) + assert.Equal(t, dyn.Location{File: file, Line: 4, Column: 5}, features.Index(0).Location()) assert.Equal(t, "bluetooth", features.Index(1).AsAny()) - assert.Equal(t, config.Location{File: file, Line: 5, Column: 5}, features.Index(1).Location()) + assert.Equal(t, dyn.Location{File: file, Line: 5, Column: 5}, features.Index(1).Location()) } func TestYAMLAnchor06(t *testing.T) { file := "testdata/anchor_06.yml" self := loadYAML(t, file) - assert.NotEqual(t, config.NilValue, self) + assert.NotEqual(t, dyn.NilValue, self) greeting := self.Get("greeting1") assert.Equal(t, "Hello, World!", greeting.AsAny()) - assert.Equal(t, config.Location{File: file, Line: 2, Column: 16}, greeting.Location()) + assert.Equal(t, dyn.Location{File: file, Line: 2, Column: 16}, greeting.Location()) } func TestYAMLAnchor07(t *testing.T) { file := "testdata/anchor_07.yml" self := loadYAML(t, file) - assert.NotEqual(t, config.NilValue, self) + assert.NotEqual(t, dyn.NilValue, self) name := self.Get("person1").Get("name") assert.Equal(t, "Alice", name.AsAny()) - assert.Equal(t, config.Location{File: file, Line: 5, Column: 9}, name.Location()) + assert.Equal(t, dyn.Location{File: file, Line: 5, Column: 9}, name.Location()) age := self.Get("person1").Get("age") assert.Equal(t, 25, age.AsAny()) - assert.Equal(t, config.Location{File: file, Line: 2, Column: 13}, age.Location()) + assert.Equal(t, dyn.Location{File: file, Line: 2, Column: 13}, age.Location()) } func TestYAMLAnchor08(t *testing.T) { file := "testdata/anchor_08.yml" self := loadYAML(t, file) - assert.NotEqual(t, config.NilValue, self) + assert.NotEqual(t, dyn.NilValue, self) username := self.Get("user1").Get("username") assert.Equal(t, "user1", username.AsAny()) - assert.Equal(t, config.Location{File: file, Line: 5, Column: 13}, username.Location()) + assert.Equal(t, dyn.Location{File: file, Line: 5, Column: 13}, username.Location()) active := self.Get("user1").Get("active") assert.Equal(t, true, active.AsAny()) - assert.Equal(t, config.Location{File: file, Line: 2, Column: 11}, active.Location()) + assert.Equal(t, dyn.Location{File: file, Line: 2, Column: 11}, active.Location()) } diff --git a/libs/config/yamlloader/yaml_error_test.go b/libs/dyn/yamlloader/yaml_error_test.go similarity index 94% rename from libs/config/yamlloader/yaml_error_test.go rename to libs/dyn/yamlloader/yaml_error_test.go index 2685042f..11c444ad 100644 --- a/libs/config/yamlloader/yaml_error_test.go +++ b/libs/dyn/yamlloader/yaml_error_test.go @@ -5,7 +5,7 @@ import ( "os" "testing" - "github.com/databricks/cli/libs/config/yamlloader" + "github.com/databricks/cli/libs/dyn/yamlloader" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gopkg.in/yaml.v3" diff --git a/libs/config/yamlloader/yaml_mix_test.go b/libs/dyn/yamlloader/yaml_mix_test.go similarity index 79% rename from libs/config/yamlloader/yaml_mix_test.go rename to libs/dyn/yamlloader/yaml_mix_test.go index 9cd0753d..307b93db 100644 --- a/libs/config/yamlloader/yaml_mix_test.go +++ b/libs/dyn/yamlloader/yaml_mix_test.go @@ -3,14 +3,14 @@ package yamlloader_test import ( "testing" - "github.com/databricks/cli/libs/config" + "github.com/databricks/cli/libs/dyn" "github.com/stretchr/testify/assert" ) func TestYAMLMix01(t *testing.T) { file := "testdata/mix_01.yml" self := loadYAML(t, file) - assert.NotEqual(t, config.NilValue, self) + assert.NotEqual(t, dyn.NilValue, self) assert.True(t, self.Get("base_address").IsAnchor()) assert.False(t, self.Get("office_address").IsAnchor()) @@ -19,7 +19,7 @@ func TestYAMLMix01(t *testing.T) { func TestYAMLMix02(t *testing.T) { file := "testdata/mix_02.yml" self := loadYAML(t, file) - assert.NotEqual(t, config.NilValue, self) + assert.NotEqual(t, dyn.NilValue, self) assert.True(t, self.Get("base_colors").IsAnchor()) assert.False(t, self.Get("theme").IsAnchor()) diff --git a/libs/config/yamlloader/yaml_test.go b/libs/dyn/yamlloader/yaml_test.go similarity index 76% rename from libs/config/yamlloader/yaml_test.go rename to libs/dyn/yamlloader/yaml_test.go index ab61f071..14269fee 100644 --- a/libs/config/yamlloader/yaml_test.go +++ b/libs/dyn/yamlloader/yaml_test.go @@ -5,14 +5,14 @@ import ( "os" "testing" - "github.com/databricks/cli/libs/config" - "github.com/databricks/cli/libs/config/yamlloader" + "github.com/databricks/cli/libs/dyn" + "github.com/databricks/cli/libs/dyn/yamlloader" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gopkg.in/yaml.v3" ) -func loadYAML(t *testing.T, path string) config.Value { +func loadYAML(t *testing.T, path string) dyn.Value { input, err := os.ReadFile(path) require.NoError(t, err) @@ -31,5 +31,5 @@ func loadYAML(t *testing.T, path string) config.Value { func TestYAMLEmpty(t *testing.T) { self := loadYAML(t, "testdata/empty.yml") - assert.Equal(t, config.NilValue, self) + assert.Equal(t, dyn.NilValue, self) }