Open magodo opened 2 weeks ago
Updated: I finally manage to do this via the following, though apparently not ideal:
package main
import (
"fmt"
"log"
"slices"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclwrite"
)
func main() {
f, diags := hclwrite.ParseConfig([]byte(`
foo = {
bar = {
}
baz = "xxx"
}
`), "main.hcl", hcl.InitialPos)
if diags.HasErrors() {
log.Fatal(diags.Error())
}
foo := f.Body().Attributes()["foo"]
tks, diags := removeExpressionAttributes(foo.Expr(), "bar")
if diags.HasErrors() {
log.Fatal(diags.Error())
}
f.Body().SetAttributeRaw("foo", tks)
fmt.Println(string(f.Bytes()))
}
func removeExpressionAttributes(expr *hclwrite.Expression, attributes ...string) (hclwrite.Tokens, hcl.Diagnostics) {
tks := expr.BuildTokens(hclwrite.TokensForIdentifier("tmp"))
ftmp, diags := hclwrite.ParseConfig(tks.Bytes(), "tmp", hcl.InitialPos)
if diags.HasErrors() {
return nil, diags
}
body := ftmp.Body().Blocks()[0].Body()
bodyAttributes := body.Attributes()
var objectAttrTokens []hclwrite.ObjectAttrTokens
for attrName, attr := range bodyAttributes {
if slices.Contains(attributes, attrName) {
continue
}
objectAttrTokens = append(objectAttrTokens, hclwrite.ObjectAttrTokens{
Name: hclwrite.TokensForIdentifier(attrName),
Value: attr.Expr().BuildTokens(nil),
})
}
return hclwrite.TokensForObject(objectAttrTokens), nil
}
Any idea about how to do this idiomatically would be appreciated!
I have a piece of code using
hclwrite
to modify some Terraform code, in that it will conditionally remove attributes/blocks. The question raises when I encounter, e.g. the following HCL (regarded as a TF attribute):(The above code is not prevalent in SDKv2 based providers, but will prevail for FW based ones as attributes are preferred to blocks)
I don't know how could I, e.g., remove the
bar
inside thefoo
attribute's expression (i.e. thecollectionValue
).I've tried with something similar to below, but doesn't output what I expected: