// Copyright 2016-2022, Pulumi Corporation. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package deploy import ( "github.com/pulumi/pulumi/sdk/v3/go/common/resource" ) // Simplifies non-mutating edits on resource.State type stateBuilder struct { state resource.State original *resource.State edited bool } func newStateBuilder(state *resource.State) *stateBuilder { return &stateBuilder{*(state.Copy()), state, false} } func (sb *stateBuilder) withUpdatedURN(update func(resource.URN) resource.URN) *stateBuilder { sb.setURN(&sb.state.URN, update(sb.state.URN)) return sb } func (sb *stateBuilder) withUpdatedParent(update func(resource.URN) resource.URN) *stateBuilder { if sb.state.Parent != "" { sb.setURN(&sb.state.Parent, update(sb.state.Parent)) } return sb } func (sb *stateBuilder) withUpdatedProvider(update func(string) string) *stateBuilder { if sb.state.Provider != "" { sb.setString(&sb.state.Provider, update(sb.state.Provider)) } return sb } func (sb *stateBuilder) withUpdatedDependencies(update func(resource.URN) resource.URN) *stateBuilder { var edited bool edited, sb.state.Dependencies = sb.updateURNSlice(sb.state.Dependencies, update) sb.edited = sb.edited || edited return sb } func (sb *stateBuilder) withUpdatedPropertyDependencies(update func(resource.URN) resource.URN) *stateBuilder { m := map[resource.PropertyKey][]resource.URN{} edited := false for k, urns := range sb.state.PropertyDependencies { var edit bool edit, m[k] = sb.updateURNSlice(urns, update) edited = edited || edit } if edited { sb.state.PropertyDependencies = m } sb.edited = sb.edited || edited return sb } // Removes all "Aliases" from the state. Once URN normalisation is done we don't want to write aliases out. func (sb *stateBuilder) withUpdatedAliases() *stateBuilder { if len(sb.state.Aliases) > 0 { sb.state.Aliases = nil sb.edited = true } return sb } func (sb *stateBuilder) build() *resource.State { if !sb.edited { return sb.original } return &sb.state } // internal func (sb *stateBuilder) setString(loc *string, value string) { if *loc == value { return } sb.edited = true *loc = value } // internal func (sb *stateBuilder) setURN(loc *resource.URN, value resource.URN) { if *loc == value { return } sb.edited = true *loc = value } // internal func (sb *stateBuilder) updateURNSlice( slice []resource.URN, update func(resource.URN) resource.URN, ) (bool, []resource.URN) { needsUpdate := false for _, urn := range slice { if update(urn) != urn { needsUpdate = true break } } if !needsUpdate { return false, slice } updated := make([]resource.URN, len(slice)) for i, urn := range slice { updated[i] = update(urn) } return true, updated }