plans: Track RequiredReplace as a cty.PathSet

We were previously tracking this as a []cty.Path, but having it turned
into a pathset on creation makes downstream use of it more convenient and
ensures that it'll obey expected invariants like not containing the same
path twice.
This commit is contained in:
Martin Atkins 2018-08-29 11:25:09 -07:00
parent d54b52fa01
commit 1ced176fc6
3 changed files with 7 additions and 12 deletions

View File

@ -95,7 +95,7 @@ type ResourceInstanceChange struct {
// //
// This is retained only for UI-plan-rendering purposes and so it does not // This is retained only for UI-plan-rendering purposes and so it does not
// currently survive a round-trip through a saved plan file. // currently survive a round-trip through a saved plan file.
RequiredReplace []cty.Path RequiredReplace cty.PathSet
// Private allows a provider to stash any extra data that is opaque to // Private allows a provider to stash any extra data that is opaque to
// Terraform that relates to this change. Terraform will save this // Terraform that relates to this change. Terraform will save this

View File

@ -40,7 +40,7 @@ type ResourceInstanceChangeSrc struct {
// //
// This is retained only for UI-plan-rendering purposes and so it does not // This is retained only for UI-plan-rendering purposes and so it does not
// currently survive a round-trip through a saved plan file. // currently survive a round-trip through a saved plan file.
RequiredReplace []cty.Path RequiredReplace cty.PathSet
// Private allows a provider to stash any extra data that is opaque to // Private allows a provider to stash any extra data that is opaque to
// Terraform that relates to this change. Terraform will save this // Terraform that relates to this change. Terraform will save this
@ -80,11 +80,7 @@ func (rcs *ResourceInstanceChangeSrc) DeepCopy() *ResourceInstanceChangeSrc {
} }
ret := *rcs ret := *rcs
if len(ret.RequiredReplace) != 0 { ret.RequiredReplace = cty.NewPathSet(ret.RequiredReplace.List()...)
rr := make([]cty.Path, len(ret.RequiredReplace))
copy(rr, ret.RequiredReplace)
ret.RequiredReplace = rr
}
if len(ret.Private) != 0 { if len(ret.Private) != 0 {
private := make([]byte, len(ret.Private)) private := make([]byte, len(ret.Private))

View File

@ -182,9 +182,8 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) {
// actually changed -- particularly after we may have undone some of the // actually changed -- particularly after we may have undone some of the
// changes in processIgnoreChanges -- so now we'll filter that list to // changes in processIgnoreChanges -- so now we'll filter that list to
// include only where changes are detected. // include only where changes are detected.
var reqRep []cty.Path reqRep := cty.NewPathSet()
if len(resp.RequiresReplace) > 0 { if len(resp.RequiresReplace) > 0 {
reqRep = make([]cty.Path, 0, len(resp.RequiresReplace))
for _, path := range resp.RequiresReplace { for _, path := range resp.RequiresReplace {
if priorVal.IsNull() { if priorVal.IsNull() {
// If prior is null then we don't expect any RequiresReplace at all, // If prior is null then we don't expect any RequiresReplace at all,
@ -212,12 +211,12 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) {
if err != nil { if err != nil {
// Should never happen since prior and changed should be of // Should never happen since prior and changed should be of
// the same type, but we'll allow it for robustness. // the same type, but we'll allow it for robustness.
reqRep = append(reqRep, path) reqRep.Add(path)
} }
if priorChangedVal != cty.NilVal { if priorChangedVal != cty.NilVal {
eqV := plannedChangedVal.Equals(priorChangedVal) eqV := plannedChangedVal.Equals(priorChangedVal)
if !eqV.IsKnown() || eqV.False() { if !eqV.IsKnown() || eqV.False() {
reqRep = append(reqRep, path) reqRep.Add(path)
} }
} }
} }
@ -235,7 +234,7 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) {
action = plans.Create action = plans.Create
case eq: case eq:
action = plans.NoOp action = plans.NoOp
case len(reqRep) > 0: case !reqRep.Empty():
// If there are any "requires replace" paths left _after our filtering // If there are any "requires replace" paths left _after our filtering
// above_ then this is a replace action. // above_ then this is a replace action.
action = plans.Replace action = plans.Replace