diff --git a/bundle/tests/loader.go b/bundle/tests/loader.go index e7cf18f7..8eddcf9a 100644 --- a/bundle/tests/loader.go +++ b/bundle/tests/loader.go @@ -7,6 +7,7 @@ import ( "github.com/databricks/cli/bundle" "github.com/databricks/cli/bundle/config/mutator" "github.com/databricks/cli/bundle/phases" + "github.com/databricks/cli/libs/diag" "github.com/stretchr/testify/require" ) @@ -20,9 +21,18 @@ func load(t *testing.T, path string) *bundle.Bundle { } func loadTarget(t *testing.T, path, env string) *bundle.Bundle { + b, diags := loadTargetWithDiags(path, env) + require.NoError(t, diags.Error()) + return b +} + +func loadTargetWithDiags(path, env string) (*bundle.Bundle, diag.Diagnostics) { ctx := context.Background() b, err := bundle.Load(ctx, path) - require.NoError(t, err) + if err != nil { + return nil, diag.FromErr(err) + } + diags := bundle.Apply(ctx, b, bundle.Seq( phases.LoadNamedTarget(env), mutator.RewriteSyncPaths(), @@ -30,6 +40,5 @@ func loadTarget(t *testing.T, path, env string) *bundle.Bundle { mutator.MergeJobTasks(), mutator.MergePipelineClusters(), )) - require.NoError(t, diags.Error()) - return b + return b, diags } diff --git a/bundle/tests/yaml_anchors_separate_block/databricks.yml b/bundle/tests/yaml_anchors_separate_block/databricks.yml new file mode 100644 index 00000000..447d5d0b --- /dev/null +++ b/bundle/tests/yaml_anchors_separate_block/databricks.yml @@ -0,0 +1,15 @@ +bundle: + name: yaml_anchors_separate_block + +tags: &custom_tags + Tag1: "Value1" + Tag2: "Value2" + Tag3: "Value3" + +resources: + jobs: + my_job: + tasks: + - task_key: yaml_anchors_separate_block + tags: + <<: *custom_tags diff --git a/bundle/tests/yaml_anchors_test.go b/bundle/tests/yaml_anchors_test.go index 95cec30a..5c849705 100644 --- a/bundle/tests/yaml_anchors_test.go +++ b/bundle/tests/yaml_anchors_test.go @@ -19,6 +19,18 @@ func TestYAMLAnchors(t *testing.T) { require.NotNil(t, t0) require.NotNil(t, t1) + require.NotNil(t, t0.NewCluster) + require.NotNil(t, t1.NewCluster) assert.Equal(t, "10.4.x-scala2.12", t0.NewCluster.SparkVersion) assert.Equal(t, "10.4.x-scala2.12", t1.NewCluster.SparkVersion) } + +func TestYAMLAnchorsNoWarnings(t *testing.T) { + _, diags := loadTargetWithDiags("./yaml_anchors", "default") + assert.Empty(t, diags) +} + +func TestYAMLAnchorsSeparateBlockNoWarnings(t *testing.T) { + _, diags := loadTargetWithDiags("./yaml_anchors_separate_block", "default") + assert.Empty(t, diags) +} diff --git a/libs/dyn/convert/normalize.go b/libs/dyn/convert/normalize.go index 296e2abb..b4bee977 100644 --- a/libs/dyn/convert/normalize.go +++ b/libs/dyn/convert/normalize.go @@ -89,14 +89,17 @@ func (n normalizeOptions) normalizeStruct(typ reflect.Type, src dyn.Value, seen for _, pair := range src.MustMap().Pairs() { pk := pair.Key pv := pair.Value + index, ok := info.Fields[pk.MustString()] if !ok { - diags = diags.Append(diag.Diagnostic{ - Severity: diag.Warning, - Summary: fmt.Sprintf("unknown field: %s", pk.MustString()), - Location: pk.Location(), - Path: path, - }) + if !pv.IsAnchor() { + diags = diags.Append(diag.Diagnostic{ + Severity: diag.Warning, + Summary: fmt.Sprintf("unknown field: %s", pk.MustString()), + Location: pk.Location(), + Path: path, + }) + } continue } diff --git a/libs/dyn/convert/normalize_test.go b/libs/dyn/convert/normalize_test.go index 133eaef8..1a0869a9 100644 --- a/libs/dyn/convert/normalize_test.go +++ b/libs/dyn/convert/normalize_test.go @@ -659,3 +659,23 @@ func TestNormalizeFloatError(t *testing.T) { Path: dyn.EmptyPath, }, err[0]) } + +func TestNormalizeAnchors(t *testing.T) { + type Tmp struct { + Foo string `json:"foo"` + } + + var typ Tmp + vin := dyn.V(map[string]dyn.Value{ + "foo": dyn.V("bar"), + "anchor": dyn.V("anchor").MarkAnchor(), + }) + + vout, err := Normalize(typ, vin) + assert.Len(t, err, 0) + + // The field that can be mapped to the struct field is retained. + assert.Equal(t, map[string]any{ + "foo": "bar", + }, vout.AsAny()) +}