Skip to content

Commit d0f4597

Browse files
author
Ivan De Marino
committed
Update helpers with a pathutils sub-package to help with the new path.Expressions manipulation
1 parent 398db10 commit d0f4597

3 files changed

Lines changed: 83 additions & 26 deletions

File tree

helpers/pathutils/merge.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package pathutils
2+
3+
import (
4+
"github.com/hashicorp/terraform-plugin-framework/path"
5+
)
6+
7+
// MergeExpressionsWithAttribute returns the given path.Expressions,
8+
// but each has been merged with the given attribute path.Expression,
9+
// and then resolved.
10+
//
11+
// Additionally, if the attribute path.Expression was not part of the initial slice,
12+
// it is added to the result.
13+
func MergeExpressionsWithAttribute(pathExps path.Expressions, attrPathExp path.Expression) path.Expressions {
14+
result := make(path.Expressions, 0, len(pathExps)+1)
15+
16+
// First, add the attribute own path expression to the result
17+
result = append(result, attrPathExp)
18+
19+
for _, pe := range pathExps {
20+
mpe := attrPathExp.Merge(pe).Resolve()
21+
22+
// Include the merged path expression,
23+
// only if it's not the same as the attribute
24+
if !mpe.Equal(attrPathExp) {
25+
result = append(result, mpe)
26+
}
27+
}
28+
29+
return result
30+
}

helpers/pathutils/resolve.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package pathutils
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag"
8+
"github.com/hashicorp/terraform-plugin-framework/diag"
9+
"github.com/hashicorp/terraform-plugin-framework/path"
10+
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
11+
)
12+
13+
// PathMatchExpressionsAgainstAttributeConfig returns the path.Paths matching the given path.Expressions.
14+
//
15+
// Each path.Expression has been merged with the given attribute path.Expression
16+
// (likely from the tfsdk.ValidateAttributeRequest), resolved,
17+
// and then matched against the given attribute tfsdk.Config (also from the tfsdk.ValidateAttributeRequest).
18+
//
19+
// This is useful for tfsdk.AttributeValidator that accept path.Expressions, and validate the attributes matching
20+
// to the expressions, in relation to the attribute the validator is applied to.
21+
// For example usage, please look at the `schemavalidator` package in this repository.
22+
func PathMatchExpressionsAgainstAttributeConfig(ctx context.Context, pathExps path.Expressions, attrPathExp path.Expression, attrConfig tfsdk.Config) (path.Paths, diag.Diagnostics) {
23+
var resDiags diag.Diagnostics
24+
25+
pathExpressions := MergeExpressionsWithAttribute(pathExps, attrPathExp)
26+
27+
resPaths := make(path.Paths, 0, len(pathExpressions))
28+
29+
for _, pe := range pathExpressions {
30+
// Retrieve all the attribute paths that match the given expressions
31+
matchingPaths, diags := attrConfig.PathMatches(ctx, pe)
32+
resDiags.Append(diags...)
33+
if diags.HasError() {
34+
return nil, resDiags
35+
}
36+
37+
// Confirm at least one attribute was matched.
38+
// If not, collect errors so that the callee can bubble the bugs up.
39+
if len(matchingPaths) == 0 {
40+
resDiags.Append(validatordiag.BugInProviderDiagnostic(fmt.Sprintf("Path expression %q matches no attribute", pe)))
41+
}
42+
43+
resPaths = append(resPaths, matchingPaths...)
44+
}
45+
46+
return resPaths, resDiags
47+
}

helpers/validatordiag/diag.go

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ func InvalidAttributeValueMatchDiagnostic(path path.Path, description string, va
3535
)
3636
}
3737

38-
// InvalidAttributeSchemaDiagnostic returns an error Diagnostic to be used when a schemavalidator of attributes is invalid.
39-
func InvalidAttributeSchemaDiagnostic(path path.Path, description string) diag.Diagnostic {
38+
// InvalidAttributeCombinationDiagnostic returns an error Diagnostic to be used when a schemavalidator of attributes is invalid.
39+
func InvalidAttributeCombinationDiagnostic(path path.Path, description string) diag.Diagnostic {
4040
return diag.NewAttributeErrorDiagnostic(
4141
path,
4242
"Invalid Attribute Combination",
@@ -53,30 +53,10 @@ func InvalidAttributeTypeDiagnostic(path path.Path, description string, value st
5353
)
5454
}
5555

56-
// ErrorsCount returns the amount of diag.Diagnostic in diag.Diagnostics that are diag.SeverityError.
57-
func ErrorsCount(diags diag.Diagnostics) int {
58-
count := 0
59-
60-
for _, d := range diags {
61-
if diag.SeverityError == d.Severity() {
62-
count++
63-
}
64-
}
65-
66-
return count
67-
}
68-
69-
// WarningsCount returns the amount of diag.Diagnostic in diag.Diagnostics that are diag.SeverityWarning.
70-
func WarningsCount(diags diag.Diagnostics) int {
71-
count := 0
72-
73-
for _, d := range diags {
74-
if diag.SeverityWarning == d.Severity() {
75-
count++
76-
}
77-
}
78-
79-
return count
56+
func BugInProviderDiagnostic(summary string) diag.Diagnostic {
57+
return diag.NewErrorDiagnostic(summary,
58+
"This is a bug in the provider, which should be reported in the provider's own issue tracker",
59+
)
8060
}
8161

8262
// capitalize will uppercase the first letter in a UTF-8 string.

0 commit comments

Comments
 (0)