Skip to content

First stab at attr.TypeWithModifyPlan. #162

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/162.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:feature
Added support for a ModifyPlan method on the `attr.Type` type, allowing custom types to include plan modification logic that will be applied to every attribute or element using that type.
```
11 changes: 11 additions & 0 deletions attr/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,17 @@ type TypeWithValidate interface {
Validate(context.Context, tftypes.Value, *tftypes.AttributePath) diag.Diagnostics
}

// TypeWithModifyPlan extends the Type interface to include a ModifyPlan method,
// used to bundle consistent plan modification logic with the Type.
type TypeWithModifyPlan interface {
Type

// ModifyPlan returns the Value that should be used in the plan. It is
// generally used to suppress diffs that do not correspond to semantic
// differences. In these cases, the `state` Value should be returned.
ModifyPlan(ctx context.Context, state, plan Value, path *tftypes.AttributePath) (Value, diag.Diagnostics)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open question: Should these also have access to the configuration value?

}

// TypeWithPlaintextDescription extends the Type interface to include a
// Description method, used to bundle extra information to include in attribute
// descriptions with the Type. It expects the description to be written as
Expand Down
19 changes: 19 additions & 0 deletions tfsdk/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,21 @@ func (s *server) planResourceChange(ctx context.Context, req *tfprotov6.PlanReso
return
}

// Execute any attr.TypeWithModifyPlans
//
// We do this first because type plan modifications should be
// overridable by resource and attribute level plan modifications. As a
// rule of thumb, more specific plan modifiers should happen after more
// generic plan modifiers.
//
// We only do this if there's a plan to modify; otherwise, it
// represents a resource being deleted and there's no point.
newPlan, ok := runTypePlanModifiers(ctx, state, plan, resourceSchema, resp)
if !ok {
return
}
plan = newPlan

// Execute any AttributePlanModifiers.
//
// This pass is before any Computed-only attributes are marked as unknown
Expand Down Expand Up @@ -764,6 +779,10 @@ func (s *server) planResourceChange(ctx context.Context, req *tfprotov6.PlanReso
plan = modifiedPlan
}

// TODO: execute any type plan modifiers again to allow overwriting
// unknown values. Do we even want to do that? What could the use case
// possibly be?

// Execute any AttributePlanModifiers again. This allows overwriting
// any unknown values.
//
Expand Down
Loading