in types/hcl.go [157:258]
func recursiveUpdate(old *hclwrite.Block, new *hclwrite.Block, before interface{}, after interface{}) {
// user can't use patch resource to add item to some array, so we don't need to deal with before or after is an array
beforeMap, ok1 := before.(map[string]interface{})
afterMap, ok2 := after.(map[string]interface{})
if !ok1 || !ok2 {
return
}
attrs := make(map[string]bool)
for attrName := range new.Body().Attributes() {
attrs[attrName] = true
}
for attrName := range old.Body().Attributes() {
attrs[attrName] = true
}
for attrName := range attrs {
if !reflect.DeepEqual(beforeMap[attrName], afterMap[attrName]) {
// add
if beforeMap[attrName] != nil && afterMap[attrName] == nil {
old.Body().SetAttributeRaw(attrName, new.Body().GetAttribute(attrName).Expr().BuildTokens(nil))
continue
}
// delete
if beforeMap[attrName] == nil && afterMap[attrName] != nil {
old.Body().RemoveAttribute(attrName)
continue
}
// update
if new.Body().GetAttribute(attrName) == nil {
continue
}
old.Body().SetAttributeRaw(attrName, new.Body().GetAttribute(attrName).Expr().BuildTokens(nil))
}
}
blocks := make(map[string]bool)
for _, block := range new.Body().Blocks() {
blocks[block.Type()] = true
}
for _, block := range old.Body().Blocks() {
blocks[block.Type()] = true
}
for blockName := range blocks {
if !reflect.DeepEqual(beforeMap[blockName], afterMap[blockName]) {
oldBlocks := make([]*hclwrite.Block, 0)
for _, block := range old.Body().Blocks() {
if block.Type() == blockName {
oldBlocks = append(oldBlocks, block)
}
}
newBlocks := make([]*hclwrite.Block, 0)
for _, block := range new.Body().Blocks() {
if block.Type() == blockName {
newBlocks = append(newBlocks, block)
}
}
// add
if len(newBlocks) != 0 && len(oldBlocks) == 0 {
for _, block := range newBlocks {
old.Body().AppendBlock(block)
}
continue
}
// delete
if len(newBlocks) == 0 && len(oldBlocks) != 0 {
for _, block := range oldBlocks {
old.Body().RemoveBlock(block)
}
continue
}
// update
if len(newBlocks) == len(oldBlocks) {
beforeArr := make([]interface{}, 0)
afterArr := make([]interface{}, 0)
if beforeMap[blockName] != nil {
temp, _ := beforeMap[blockName].([]interface{})
beforeArr = temp
}
if afterMap[blockName] != nil {
temp, _ := afterMap[blockName].([]interface{})
afterArr = temp
}
if len(beforeArr) != len(afterArr) && len(beforeArr) != len(oldBlocks) {
log.Fatal()
}
for index := range newBlocks {
recursiveUpdate(oldBlocks[index], newBlocks[index], beforeArr[index], afterArr[index])
}
} else {
for _, block := range oldBlocks {
old.Body().RemoveBlock(block)
}
for _, block := range newBlocks {
old.Body().AppendBlock(block)
}
}
}
}
}