From fb7ec6ba17207c4edfdddb59153fc30a77794247 Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Fri, 22 Dec 2023 13:41:37 +0100 Subject: [PATCH] Rename libs/config -> libs/dyn The name "dynamic value", or "dyn" for short, is more descriptive than the opaque "config". Also, it conveniently does not alias with other packages in the repository, or (popular ones) elsewhere. --- libs/config/path_test.go | 76 ------- libs/diag/diagnostic.go | 4 +- .../convert/end_to_end_test.go | 4 +- libs/{config => dyn}/convert/error.go | 4 +- libs/{config => dyn}/convert/from_typed.go | 108 +++++----- .../convert/from_typed_test.go | 186 +++++++++--------- libs/{config => dyn}/convert/normalize.go | 96 ++++----- .../{config => dyn}/convert/normalize_test.go | 132 ++++++------- libs/{config => dyn}/convert/struct_info.go | 14 +- .../convert/struct_info_test.go | 8 +- libs/{config => dyn}/convert/to_typed.go | 54 ++--- libs/{config => dyn}/convert/to_typed_test.go | 126 ++++++------ libs/{config => dyn}/kind.go | 2 +- libs/{config => dyn}/location.go | 2 +- libs/{config => dyn}/location_test.go | 6 +- libs/{config => dyn}/merge/merge.go | 40 ++-- libs/{config => dyn}/merge/merge_test.go | 76 +++---- libs/{config => dyn}/path.go | 2 +- libs/{config => dyn}/path_string.go | 2 +- libs/{config => dyn}/path_string_test.go | 4 +- libs/dyn/path_test.go | 76 +++++++ libs/{config => dyn}/value.go | 2 +- libs/{config => dyn}/value_test.go | 22 +-- libs/{config => dyn}/walk.go | 2 +- libs/{config => dyn}/walk_test.go | 4 +- libs/{config => dyn}/yamlloader/loader.go | 80 ++++---- .../yamlloader/testdata/anchor_01.yml | 0 .../yamlloader/testdata/anchor_02.yml | 0 .../yamlloader/testdata/anchor_03.yml | 0 .../yamlloader/testdata/anchor_04.yml | 0 .../yamlloader/testdata/anchor_05.yml | 0 .../yamlloader/testdata/anchor_06.yml | 0 .../yamlloader/testdata/anchor_07.yml | 0 .../yamlloader/testdata/anchor_08.yml | 0 .../yamlloader/testdata/empty.yml | 0 .../yamlloader/testdata/error_01.yml | 0 .../yamlloader/testdata/error_02.yml | 0 .../yamlloader/testdata/error_03.yml | 0 .../yamlloader/testdata/mix_01.yml | 0 .../yamlloader/testdata/mix_02.yml | 0 libs/{config => dyn}/yamlloader/yaml.go | 8 +- .../yamlloader/yaml_anchor_test.go | 44 ++--- .../yamlloader/yaml_error_test.go | 2 +- .../yamlloader/yaml_mix_test.go | 6 +- libs/{config => dyn}/yamlloader/yaml_test.go | 8 +- 45 files changed, 600 insertions(+), 600 deletions(-) delete mode 100644 libs/config/path_test.go rename libs/{config => dyn}/convert/end_to_end_test.go (93%) rename libs/{config => dyn}/convert/error.go (73%) rename libs/{config => dyn}/convert/from_typed.go (58%) rename libs/{config => dyn}/convert/from_typed_test.go (60%) rename libs/{config => dyn}/convert/normalize.go (58%) rename libs/{config => dyn}/convert/normalize_test.go (74%) rename libs/{config => dyn}/convert/struct_info.go (87%) rename libs/{config => dyn}/convert/struct_info_test.go (97%) rename libs/{config => dyn}/convert/to_typed.go (81%) rename libs/{config => dyn}/convert/to_typed_test.go (76%) rename libs/{config => dyn}/kind.go (98%) rename libs/{config => dyn}/location.go (92%) rename libs/{config => dyn}/location_test.go (54%) rename libs/{config => dyn}/merge/merge.go (60%) rename libs/{config => dyn}/merge/merge_test.go (67%) rename libs/{config => dyn}/path.go (99%) rename libs/{config => dyn}/path_string.go (99%) rename libs/{config => dyn}/path_string_test.go (96%) create mode 100644 libs/dyn/path_test.go rename libs/{config => dyn}/value.go (99%) rename libs/{config => dyn}/value_test.go (55%) rename libs/{config => dyn}/walk.go (99%) rename libs/{config => dyn}/walk_test.go (98%) rename libs/{config => dyn}/yamlloader/loader.go (61%) rename libs/{config => dyn}/yamlloader/testdata/anchor_01.yml (100%) rename libs/{config => dyn}/yamlloader/testdata/anchor_02.yml (100%) rename libs/{config => dyn}/yamlloader/testdata/anchor_03.yml (100%) rename libs/{config => dyn}/yamlloader/testdata/anchor_04.yml (100%) rename libs/{config => dyn}/yamlloader/testdata/anchor_05.yml (100%) rename libs/{config => dyn}/yamlloader/testdata/anchor_06.yml (100%) rename libs/{config => dyn}/yamlloader/testdata/anchor_07.yml (100%) rename libs/{config => dyn}/yamlloader/testdata/anchor_08.yml (100%) rename libs/{config => dyn}/yamlloader/testdata/empty.yml (100%) rename libs/{config => dyn}/yamlloader/testdata/error_01.yml (100%) rename libs/{config => dyn}/yamlloader/testdata/error_02.yml (100%) rename libs/{config => dyn}/yamlloader/testdata/error_03.yml (100%) rename libs/{config => dyn}/yamlloader/testdata/mix_01.yml (100%) rename libs/{config => dyn}/yamlloader/testdata/mix_02.yml (100%) rename libs/{config => dyn}/yamlloader/yaml.go (56%) rename libs/{config => dyn}/yamlloader/yaml_anchor_test.go (61%) rename libs/{config => dyn}/yamlloader/yaml_error_test.go (94%) rename libs/{config => dyn}/yamlloader/yaml_mix_test.go (79%) rename libs/{config => dyn}/yamlloader/yaml_test.go (76%) diff --git a/libs/config/path_test.go b/libs/config/path_test.go deleted file mode 100644 index 3fdd848e60..0000000000 --- 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 c5757a58e8..02d2e7c176 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 c06830e83e..fbb8433629 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 b55668d67f..d3770d82d7 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 e3911a9e5a..0659d1cd78 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 2b28f549cd..0e9b9c7cd5 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 d7d2b1dff5..7a652cbc7c 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 9c4b10bbd4..13b1ed52f5 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 80cfabb692..dc3ed4da40 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 685679aecd..08be3c47ef 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 8c43d97434..209de12cbd 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 2845bddae0..3adc94c799 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 5ed1a6650b..ba093341e9 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 534b21c2c4..cd369193e0 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 31013193c7..29226d73d0 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 896e212923..1cadbea608 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 c2e89f60a4..c4928e3536 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 f1abf48ca9..bfd93dad5b 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 9538ad27f1..0fa0c682d4 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 89e645615f..9af394c6f1 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 0000000000..c4ea26c4aa --- /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 fe0ced9bdf..9ac738f9cb 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 6c8befc7ed..5fa45f15a5 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 ce05833804..138816be6e 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 806ca256fd..1b94ad9027 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 6472c13731..899e1d7b8a 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 a3cc7284f0..a18324ffad 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 a8b666868c..05beb5401d 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 2685042fd9..11c444ad36 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 9cd0753de5..307b93dbf3 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 ab61f0718f..14269feeef 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) }