use go-cty's WrangleMarksDeep instead of UnmarkDeepWithPaths

This should improve the performance since we don't need to
remark the values again and only handle the marks we want
to deal with.
pull/38256/head
Daniel Schmidt 1 month ago
parent 2767639191
commit 2cddb70898

@ -54,22 +54,19 @@ func (d *Deprecations) ValidateAndUnmark(value cty.Value, module addrs.Module, r
// It finds the most specific range possible for each diagnostic.
func (d *Deprecations) ValidateExpressionDeepAndUnmark(value cty.Value, module addrs.Module, expr hcl.Expression) (cty.Value, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
unmarked, pvms := value.UnmarkDeepWithPaths()
undeprecatedVal, pdms := marks.GetDeprecationMarksDeep(value)
// Check if we need to suppress deprecation warnings for this module call.
if d.IsModuleCallDeprecationSuppressed(module) {
return unmarked.MarkWithPaths(marks.RemoveAll(pvms, marks.Deprecation)), diags
return undeprecatedVal, diags
}
for _, pvm := range pvms {
for m := range pvm.Marks {
if depMark, ok := m.(marks.DeprecationMark); ok {
rng := tfdiags.RangeForExpressionAtPath(expr, pvm.Path)
diags = diags.Append(deprecationMarkToDiagnostic(depMark, &rng))
}
}
for _, pdm := range pdms {
rng := tfdiags.RangeForExpressionAtPath(expr, pdm.Path)
diags = diags.Append(deprecationMarkToDiagnostic(pdm.Mark, &rng))
}
return unmarked.MarkWithPaths(marks.RemoveAll(pvms, marks.Deprecation)), diags
return undeprecatedVal, diags
}
func (d *Deprecations) deprecationMarksToDiagnostics(deprecationMarks []marks.DeprecationMark, module addrs.Module, rng *hcl.Range) tfdiags.Diagnostics {
@ -109,41 +106,34 @@ func deprecationMarkToDiagnostic(depMark marks.DeprecationMark, subject *hcl.Ran
// unless deprecation warnings are suppressed for the given module.
func (d *Deprecations) ValidateAndUnmarkConfig(value cty.Value, schema *configschema.Block, module addrs.Module) (cty.Value, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
unmarked, pvms := value.UnmarkDeepWithPaths()
undeprecatedVal, pdms := marks.GetDeprecationMarksDeep(value)
if d.IsModuleCallDeprecationSuppressed(module) {
// Even if we don't want to get deprecation warnings we want to remove the marks
return unmarked.MarkWithPaths(marks.RemoveAll(pvms, marks.Deprecation)), diags
return undeprecatedVal, diags
}
for _, pvm := range pvms {
for m := range pvm.Marks {
if depMark, ok := m.(marks.DeprecationMark); ok {
diag := tfdiags.AttributeValue(
tfdiags.Warning,
"Deprecated value used",
depMark.Message,
pvm.Path,
)
if depMark.OriginDescription != "" {
diag = tfdiags.Override(
diag,
tfdiags.Warning, // We just want to override the extra info
func() tfdiags.DiagnosticExtraWrapper {
return &tfdiags.DeprecationOriginDiagnosticExtra{
// TODO: Remove common prefixes from origin descriptions?
OriginDescription: depMark.OriginDescription,
}
})
}
diags = diags.Append(diag)
}
for _, pdm := range pdms {
diag := tfdiags.AttributeValue(
tfdiags.Warning,
"Deprecated value used",
pdm.Mark.Message,
pdm.Path,
)
if pdm.Mark.OriginDescription != "" {
diag = tfdiags.Override(
diag,
tfdiags.Warning, // We just want to override the extra info
func() tfdiags.DiagnosticExtraWrapper {
return &tfdiags.DeprecationOriginDiagnosticExtra{
OriginDescription: pdm.Mark.OriginDescription,
}
})
}
diags = diags.Append(diag)
}
return unmarked.MarkWithPaths(marks.RemoveAll(pvms, marks.Deprecation)), diags
return undeprecatedVal, diags
}
func (d *Deprecations) IsModuleCallDeprecationSuppressed(addr addrs.Module) bool {

@ -5,6 +5,7 @@ package marks
import (
"github.com/zclconf/go-cty/cty"
"github.com/zclconf/go-cty/cty/ctymarks"
)
// valueMarks allow creating strictly typed values for use as cty.Value marks.
@ -24,12 +25,11 @@ func Has(val cty.Value, mark interface{}) bool {
// For value marks Has returns true if a mark of the type is present
case DeprecationMark:
for depMark := range val.Marks() {
if _, ok := depMark.(DeprecationMark); ok {
return true
}
for range cty.ValueMarksOfType[DeprecationMark](val) {
return true
}
return false
default:
panic("Unknown mark type")
}
@ -72,26 +72,30 @@ func GetDeprecationMarks(val cty.Value) (cty.Value, []DeprecationMark) {
return unmarked.WithMarks(other), depMarks
}
// RemoveDeprecationMarks returns a copy of the given cty.Value with all
// deprecation marks removed.
func RemoveDeprecationMarks(val cty.Value) cty.Value {
newVal, marks := val.Unmark()
type PathDeprecationMark struct {
Mark DeprecationMark
Path cty.Path
}
for mark := range marks {
if _, ok := mark.(DeprecationMark); !ok {
newVal = newVal.Mark(mark)
// GetDeprecationMarksDeep returns a copy of the given cty.Value with all
// deprecation marks removed, along with a slice of all deprecation marks found
// in the value and their paths.
func GetDeprecationMarksDeep(value cty.Value) (cty.Value, []PathDeprecationMark) {
pdms := []PathDeprecationMark{}
undeprecatedVal, _ := value.WrangleMarksDeep(func(mark any, path cty.Path) (ctymarks.WrangleAction, error) {
if depMark, ok := mark.(DeprecationMark); ok {
pdms = append(pdms, PathDeprecationMark{
Mark: depMark,
Path: path.Copy(),
})
// We want to drop the deprecation marks
return ctymarks.WrangleDrop, nil
}
}
return newVal
}
// and ignore all other marks
return ctymarks.WrangleKeep, nil
})
// RemoveDeprecationMarksDeep returns a copy of the given cty.Value with all
// deprecation marks deeply removed.
func RemoveDeprecationMarksDeep(val cty.Value) cty.Value {
newVal, pvms := val.UnmarkDeepWithPaths()
otherPvms := RemoveAll(pvms, Deprecation)
return newVal.MarkWithPaths(otherPvms)
return undeprecatedVal, pdms
}
// Sensitive indicates that this value is marked as sensitive in the context of

@ -90,7 +90,7 @@ func (ev *forEachEvaluator) ResourceValue() (map[string]cty.Value, bool, tfdiags
return res, false, diags
}
forEachVal = marks.RemoveDeprecationMarks(forEachVal)
forEachVal, _ = marks.GetDeprecationMarks(forEachVal)
if forEachVal.IsNull() || !forEachVal.IsKnown() || markSafeLengthInt(forEachVal) == 0 {
// we check length, because an empty set returns a nil map which will panic below
return res, true, diags

@ -521,7 +521,7 @@ If you do intend to export this data, annotate the output value as sensitive by
}
if n.Config.DeprecatedSet {
val = marks.RemoveDeprecationMarksDeep(val)
val, _ = marks.GetDeprecationMarksDeep(val)
if n.Addr.Module.IsRoot() {
diags = diags.Append(&hcl.Diagnostic{
Severity: hcl.DiagError,

Loading…
Cancel
Save