Skip to content

Commit 02689b7

Browse files
authored
path: Introduce package with initial tftypes.AttributePath abstraction (#390)
* path: Introduce package with initial tftypes.AttributePath abstraction Reference: #81 Reference: #161 Reference: #172 Reference: #365 This introduces a native abstraction over terraform-plugin-go's `tftypes.AttributePath`, allowing the framework to own the implementation details and extend the functionality further. Provider developers will be closer to removing a direct dependency on terraform-plugin-go. This is a major breaking change, however it is necessary before 1.0 to prevent compatibility issues in the future. This functionality is only intended to replace `tftypes.AttributePath` usage and not mess with the `tfsdk.Config`, `tfsdk.Plan`, and `tfsdk.State` type `tftypes.Value` data storage fields or their underlying data manipulation logic. This does leave the framework in an awkward half-state until those are further refactored (likely towards native `attr.Value`), but is done to try and reduce the review complexity of this initial migration. Additional followup changes will introduce the concept of path expressions, which will allow provider developers to match against multiple paths or reference parent paths in schema-based plan modifier and validation functionality. To prevent import cycles between `attr` and `diag` packages due changing the `attr.TypeWithValidate` type `Validate` method signature from `Validate(context.Context, tftypes.Value, *tftypes.AttributePath) diag.Diagnostics` to `Validate(context.Context, tftypes.Value, path.Path) diag.Diagnostics`, the `TypeWithValidation` interface is moved a new `xattr` package underneath `attr` with Go and website documentation to direct provider developers to the other package. This will also solve a prior issue with trying to implement `TypeWithModifyPlan` support. Naming and location of anything in this initial implementation can be adjusted as necessary. Provider developers can migrate to the new path handling by replacing: ```go tftypes.NewAttributePath().WithAttributeName("example") ``` With the equivalent: ```go path.Root("example") ``` Then using the `(Path).At*` methods to extend the path definition instead of `(*tftypes.AttributePath).With*` methods: | Current | New | | ------------------------ | --------------- | | `WithAttributeName()` | `AtName()` | | `WithElementKeyInt()` | `AtListIndex()` | | `WithElementKeyString()` | `AtMapKey()` | | `WithElementKeyValue()` | `AtSetValue()` |
1 parent 6e01dca commit 02689b7

File tree

140 files changed

+4030
-1281
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

140 files changed

+4030
-1281
lines changed

.changelog/390.txt

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
```release-note:note
2+
Attribute path handling is now included in the `path` package of this Go module, rather than being dependent on low level terraform-plugin-go types. To migrate, `tftypes.NewAttributePath().WithAttributeName(` can be replaced with `path.Root(`, then subsequent step replacements are `WithAttributeName` to `AtName`, `WithElementKeyInt` to `AtListIndex`, `WithElementKeyString` to `AtMapKey`, and `WithElementKeyValue` to `AtSetValue`. For example, `tftypes.NewAttributePath().WithAttributeName("parent_attr").WithElementKeyInt(0).WithAttributeName("nested_attr")` should become `path.Root("parent_attr").AtListIndex(0).AtName("nested_attr")`.
3+
```
4+
5+
```release-note:feature
6+
path: Introduced framework abstraction for attribute path handling
7+
```
8+
9+
```release-note:breaking-change
10+
attr: The `TypeWithValidate` interface has been moved under the `attr/xattr` package and the `*tftypes.AttributePath` parameter is replaced with `path.Path`
11+
```
12+
13+
```release-note:breaking-change
14+
diag: The `NewAttributeErrorDiagnostic` and `NewAttributeWarningDiagnostic` function `*tftypes.AttributePath` parameters are replaced with `path.Path`
15+
```
16+
17+
```release-note:breaking-change
18+
diag: The `DiagnosticWithPath` interface `Path` method `*tftypes.AttributePath` return is replaced with `path.Path`
19+
```
20+
21+
```release-note:breaking-change
22+
diag: The `Diagnostics` type `AddAttributeError` and `AddAttributeWarning` method `*tftypes.AttributePath` parameters are replaced with `path.Path`
23+
```
24+
25+
```release-note:breaking-change
26+
tfsdk: The `Config`, `Plan`, and `State` types `GetAttribute` and `SetAttribute` methods `*tftypes.AttributePath` parameters are replaced with `path.Path`
27+
```
28+
29+
```release-note:breaking-change
30+
tfsdk: The `ModifyAttributePlanRequest`, `ModifyResourcePlanResponse`, and `ValidateAttributeRequest` type `AttributePath *tftypes.AttributePath` fields are replaced with `AttributePath path.Path`
31+
```
32+
33+
```release-note:breaking-change
34+
tfsdk: The `RequiresReplaceIf` and `ResourceImportStatePassthroughID` function `*tftypes.AttributePath` parameters are replaced with `path.Path`
35+
```

attr/doc.go

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Package attr contains type and value interfaces for core framework and
2+
// provider-defined data types. The underlying xattr package contains
3+
// additional interfaces for advanced type functionality.
4+
package attr

attr/type.go

+3-13
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ package attr
33
import (
44
"context"
55

6-
"github.com/hashicorp/terraform-plugin-framework/diag"
76
"github.com/hashicorp/terraform-plugin-go/tftypes"
87
)
98

109
// Type defines an interface for describing a kind of attribute. Types are
1110
// collections of constraints and behaviors such that they can be reused on
1211
// multiple attributes easily.
12+
//
13+
// Refer also to the xattr package, which contains additional extensions for
14+
// Type, such as validation.
1315
type Type interface {
1416
// TerraformType returns the tftypes.Type that should be used to
1517
// represent this type. This constrains what user input will be
@@ -74,18 +76,6 @@ type TypeWithElementTypes interface {
7476
ElementTypes() []Type
7577
}
7678

77-
// TypeWithValidate extends the Type interface to include a Validate method,
78-
// used to bundle consistent validation logic with the Type.
79-
type TypeWithValidate interface {
80-
Type
81-
82-
// Validate returns any warnings or errors about the value that is
83-
// being used to populate the Type. It is generally used to check the
84-
// data format and ensure that it complies with the requirements of the
85-
// Type.
86-
Validate(context.Context, tftypes.Value, *tftypes.AttributePath) diag.Diagnostics
87-
}
88-
8979
// TypeWithPlaintextDescription extends the Type interface to include a
9080
// Description method, used to bundle extra information to include in attribute
9181
// descriptions with the Type. It expects the description to be written as

attr/xattr/doc.go

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Package xattr contains additional interfaces for attr types. This package
2+
// is separate from the core attr package to prevent import cycles.
3+
package xattr

attr/xattr/type.go

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package xattr
2+
3+
import (
4+
"context"
5+
6+
"github.com/hashicorp/terraform-plugin-framework/attr"
7+
"github.com/hashicorp/terraform-plugin-framework/diag"
8+
"github.com/hashicorp/terraform-plugin-framework/path"
9+
"github.com/hashicorp/terraform-plugin-go/tftypes"
10+
)
11+
12+
// TypeWithValidate extends the attr.Type interface to include a Validate
13+
// method, used to bundle consistent validation logic with the Type.
14+
type TypeWithValidate interface {
15+
attr.Type
16+
17+
// Validate returns any warnings or errors about the value that is
18+
// being used to populate the Type. It is generally used to check the
19+
// data format and ensure that it complies with the requirements of the
20+
// Type.
21+
Validate(context.Context, tftypes.Value, path.Path) diag.Diagnostics
22+
}

diag/attribute_error_diagnostic.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package diag
22

33
import (
4-
"github.com/hashicorp/terraform-plugin-go/tftypes"
4+
"github.com/hashicorp/terraform-plugin-framework/path"
55
)
66

77
// NewAttributeErrorDiagnostic returns a new error severity diagnostic with the given summary, detail, and path.
8-
func NewAttributeErrorDiagnostic(path *tftypes.AttributePath, summary string, detail string) DiagnosticWithPath {
8+
func NewAttributeErrorDiagnostic(path path.Path, summary string, detail string) DiagnosticWithPath {
99
return withPath{
1010
Diagnostic: NewErrorDiagnostic(summary, detail),
1111
path: path,

diag/attribute_warning_diagnostic.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package diag
22

33
import (
4-
"github.com/hashicorp/terraform-plugin-go/tftypes"
4+
"github.com/hashicorp/terraform-plugin-framework/path"
55
)
66

77
// NewAttributeWarningDiagnostic returns a new warning severity diagnostic with the given summary, detail, and path.
8-
func NewAttributeWarningDiagnostic(path *tftypes.AttributePath, summary string, detail string) DiagnosticWithPath {
8+
func NewAttributeWarningDiagnostic(path path.Path, summary string, detail string) DiagnosticWithPath {
99
return withPath{
1010
Diagnostic: NewWarningDiagnostic(summary, detail),
1111
path: path,

diag/diagnostic.go

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package diag
22

3-
import (
4-
"github.com/hashicorp/terraform-plugin-go/tftypes"
5-
)
3+
import "github.com/hashicorp/terraform-plugin-framework/path"
64

75
// Diagnostic is an interface for providing enhanced feedback.
86
//
@@ -48,5 +46,5 @@ type DiagnosticWithPath interface {
4846
//
4947
// If present, this enables the display of source configuration context for
5048
// supporting implementations such as Terraform CLI commands.
51-
Path() *tftypes.AttributePath
49+
Path() path.Path
5250
}

diag/diagnostics.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package diag
22

33
import (
4-
"github.com/hashicorp/terraform-plugin-go/tftypes"
4+
"github.com/hashicorp/terraform-plugin-framework/path"
55
)
66

77
// Diagnostics represents a collection of diagnostics.
@@ -11,12 +11,12 @@ import (
1111
type Diagnostics []Diagnostic
1212

1313
// AddAttributeError adds a generic attribute error diagnostic to the collection.
14-
func (diags *Diagnostics) AddAttributeError(path *tftypes.AttributePath, summary string, detail string) {
14+
func (diags *Diagnostics) AddAttributeError(path path.Path, summary string, detail string) {
1515
diags.Append(NewAttributeErrorDiagnostic(path, summary, detail))
1616
}
1717

1818
// AddAttributeWarning adds a generic attribute warning diagnostic to the collection.
19-
func (diags *Diagnostics) AddAttributeWarning(path *tftypes.AttributePath, summary string, detail string) {
19+
func (diags *Diagnostics) AddAttributeWarning(path path.Path, summary string, detail string) {
2020
diags.Append(NewAttributeWarningDiagnostic(path, summary, detail))
2121
}
2222

0 commit comments

Comments
 (0)