diff --git a/bundle/config/mutator/validate_unique_resource_keys.go b/bundle/config/mutator/validate_unique_resource_keys.go deleted file mode 100644 index d3cb5446..00000000 --- a/bundle/config/mutator/validate_unique_resource_keys.go +++ /dev/null @@ -1,77 +0,0 @@ -package mutator - -import ( - "context" - "fmt" - - "github.com/databricks/cli/bundle" - "github.com/databricks/cli/libs/diag" - "github.com/databricks/cli/libs/dyn" -) - -// TODO: Ensure the solution here works for dup keys in the same resource type. - -type validateUniqueResourceKeys struct{} - -func ValidateUniqueResourceKeys() bundle.Mutator { - return &validateUniqueResourceKeys{} -} - -func (m *validateUniqueResourceKeys) Name() string { - return "ValidateUniqueResourceKeys" -} - -// TODO: Make this a readonly mutator. -// TODO: Make this a bit terser. - -// TODO: Ensure all duplicate key sites are returned to the user in the diagnostics. -func (m *validateUniqueResourceKeys) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostics { - diags := diag.Diagnostics{} - - err := b.Config.Mutate(func(v dyn.Value) (dyn.Value, error) { - paths := make(map[string]dyn.Path) - rv := v.Get("resources") - - // Walk the resources tree and accumulate the resource identifiers. - _, err := dyn.Walk(rv, func(p dyn.Path, v dyn.Value) (dyn.Value, error) { - // The path is expected to be of length 2, and of the form .. - // Eg: jobs.my_job, pipelines.my_pipeline, etc. - if len(p) < 2 { - return v, nil - } - if len(p) > 2 { - return v, dyn.ErrSkip - } - - // If the resource identifier already exists in the map, return an error. - k := p[1].Key() - if _, ok := paths[k]; ok { - // Location of the existing resource in the map. - ov, _ := dyn.GetByPath(rv, paths[k]) - ol := ov.Location() - - // Location of the newly encountered with a duplicate name. - nv, _ := dyn.GetByPath(rv, p) - nl := nv.Location() - - // Error, encountered a duplicate resource identifier. - // TODO: Set location for one of the resources? - diags = append(diags, diag.Diagnostic{ - Severity: diag.Error, - Summary: fmt.Sprintf("multiple resources named %s (%s at %s, %s at %s)", k, paths[k].String(), nl, p.String(), ol), - Location: nl, - }) - } - - // Accumulate the resource identifier and its path. - paths[k] = p - return v, nil - }) - return v, err - }) - if err != nil { - diags = append(diags, diag.FromErr(err)...) - } - - return diags -} diff --git a/bundle/config/root.go b/bundle/config/root.go index 1447dd35..18f26e39 100644 --- a/bundle/config/root.go +++ b/bundle/config/root.go @@ -259,12 +259,6 @@ func (r *Root) InitializeVariables(vars []string) error { } func (r *Root) Merge(other *Root) error { - // Check for safe merge, protecting against duplicate resource identifiers - // err := r.verifySafeMerge(*other) - // if err != nil { - // return err - // } - // Merge dynamic configuration values. return r.Mutate(func(root dyn.Value) (dyn.Value, error) { return merge.Merge(root, other.value) @@ -464,82 +458,3 @@ func (r Root) GetLocation(path string) dyn.Location { func (r Root) ReadOnlyValue() dyn.Value { return r.value } - -// // This function verifies that the merge of two Root objects is safe. It checks -// // there will be no duplicate resource identifiers in the merged configuration. -// func (r Root) verifySafeMerge(other Root) error { -// paths, err := r.gatherResourceIdentifiers() -// if err != nil { -// return err -// } - -// otherPaths, err := other.gatherResourceIdentifiers() -// if err != nil { -// return err -// } - -// // If duplicate keys exist, return -// for k, p := range paths { -// if _, ok := otherPaths[k]; ok { -// // Type and location of the existing resource in the map. -// ot := strings.TrimSuffix(p[0].Key(), "s") -// ov, _ := dyn.GetByPath(r.value.Get("resources"), p) -// ol := ov.Location() - -// // Type and location of the newly encountered resource with a duplicate name. -// nt := strings.TrimSuffix(otherPaths[k][0].Key(), "s") -// nv, _ := dyn.GetByPath(other.value.Get("resources"), otherPaths[k]) -// nl := nv.Location() - -// // Error, encountered a duplicate resource identifier. -// return fmt.Errorf("multiple resources named %s (%s at %v, %s at %v)", k, ot, ol, nt, nl) -// } -// } -// return nil -// } - -// // This function gathers the resource identifiers, which exist in the bundle configuration -// // in the form: resources... -// // -// // It returns an error if it encounters duplicate resource identifiers. -// // -// // Otherwise it returns a map of resource identifiers to their paths in the configuration tree, -// // relative to the resources key. -// func (r Root) gatherResourceIdentifiers() (map[string]dyn.Path, error) { -// paths := make(map[string]dyn.Path) -// rrv := r.value.Get("resources") - -// // Walk the resources tree and accumulate the resource identifiers. -// _, err := dyn.Walk(rrv, func(p dyn.Path, v dyn.Value) (dyn.Value, error) { -// // The path is expected to be of length 2, and of the form .. -// // Eg: jobs.my_job, pipelines.my_pipeline, etc. -// if len(p) < 2 { -// return v, nil -// } -// if len(p) > 2 { -// return v, dyn.ErrSkip -// } - -// // If the resource identifier already exists in the map, return an error. -// k := p[1].Key() -// if _, ok := paths[k]; ok { -// // Type and location of the existing resource in the map. -// ot := strings.TrimSuffix(paths[k][0].Key(), "s") -// ov, _ := dyn.GetByPath(rrv, paths[k]) -// ol := ov.Location() - -// // Type and location of the newly encountered with a duplicate name. -// nt := strings.TrimSuffix(p[0].Key(), "s") -// nv, _ := dyn.GetByPath(rrv, p) -// nl := nv.Location() - -// // Error, encountered a duplicate resource identifier. -// return v, fmt.Errorf("multiple resources named %s (%s at %v, %s at %v)", k, ot, ol, nt, nl) -// } - -// // Accumulate the resource identifier and its path. -// paths[k] = p -// return v, nil -// }) -// return paths, err -// }