Skip to content

Commit d013a5f

Browse files
committed
refactor
1 parent 3a28a96 commit d013a5f

File tree

2 files changed

+115
-91
lines changed

2 files changed

+115
-91
lines changed

internal/convert/convert.go

Lines changed: 53 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -228,36 +228,58 @@ func fillReplicationSpecs(resourceb *hclwrite.Body, root attrVals) error {
228228
}
229229

230230
func fillTagsLabelsOpt(resourceb *hclwrite.Body, name string) error {
231-
var (
232-
file = hclwrite.NewEmptyFile()
233-
fileb = file.Body()
234-
foundIndividual = false
235-
)
236-
d, err := getDynamicBlock(resourceb, name)
231+
tokensDynamic, err := extractTagsLabelsDynamicBlock(resourceb, name)
237232
if err != nil {
238233
return err
239234
}
240-
var tokenDynamic hclwrite.Tokens
241-
if d.forEach != nil {
242-
key := d.content.Body().GetAttribute(nKey)
243-
value := d.content.Body().GetAttribute(nValue)
244-
if key == nil || value == nil {
245-
return fmt.Errorf("dynamic block %s: %s or %s not found", name, nKey, nValue)
246-
}
247-
collectionExpr := strings.TrimSpace(string(d.forEach.Expr().BuildTokens(nil).Bytes()))
248-
keyExpr := strings.TrimSpace(strings.ReplaceAll(string(key.Expr().BuildTokens(nil).Bytes()),
249-
fmt.Sprintf("%s.%s", name, nKey), nKey))
250-
valueExpr := strings.TrimSpace(strings.ReplaceAll(string(value.Expr().BuildTokens(nil).Bytes()),
251-
fmt.Sprintf("%s.%s", name, nValue), nValue))
252-
if keyExpr == nKey && valueExpr == nValue { // expression can be simplified and use for_each expression
253-
tokenDynamic = hcl.TokensFromString(collectionExpr)
254-
} else {
255-
forExpr := strings.TrimSpace(fmt.Sprintf("for key, value in %s : %s => %s",
256-
collectionExpr, keyExpr, valueExpr))
257-
tokenDynamic = hcl.TokensObjectFromString(forExpr)
258-
}
259-
resourceb.RemoveBlock(d.block)
235+
tokensIndividual, err := extractTagsLabelsIndividual(resourceb, name)
236+
if err != nil {
237+
return err
260238
}
239+
if tokensDynamic != nil && tokensIndividual != nil {
240+
resourceb.SetAttributeRaw(name, hcl.TokensFuncMerge(tokensDynamic, tokensIndividual))
241+
return nil
242+
}
243+
if tokensDynamic != nil {
244+
resourceb.SetAttributeRaw(name, tokensDynamic)
245+
}
246+
if tokensIndividual != nil {
247+
resourceb.SetAttributeRaw(name, tokensIndividual)
248+
}
249+
return nil
250+
}
251+
252+
func extractTagsLabelsDynamicBlock(resourceb *hclwrite.Body, name string) (hclwrite.Tokens, error) {
253+
d, err := getDynamicBlock(resourceb, name)
254+
if err != nil || d.forEach == nil {
255+
return nil, err
256+
}
257+
key := d.content.Body().GetAttribute(nKey)
258+
value := d.content.Body().GetAttribute(nValue)
259+
if key == nil || value == nil {
260+
return nil, fmt.Errorf("dynamic block %s: %s or %s not found", name, nKey, nValue)
261+
}
262+
collectionExpr := strings.TrimSpace(string(d.forEach.Expr().BuildTokens(nil).Bytes()))
263+
keyExpr := strings.TrimSpace(strings.ReplaceAll(string(key.Expr().BuildTokens(nil).Bytes()),
264+
fmt.Sprintf("%s.%s", name, nKey), nKey))
265+
valueExpr := strings.TrimSpace(strings.ReplaceAll(string(value.Expr().BuildTokens(nil).Bytes()),
266+
fmt.Sprintf("%s.%s", name, nValue), nValue))
267+
forExpr := strings.TrimSpace(fmt.Sprintf("for key, value in %s : %s => %s",
268+
collectionExpr, keyExpr, valueExpr))
269+
tokenDynamic := hcl.TokensObjectFromExpr(forExpr)
270+
if keyExpr == nKey && valueExpr == nValue { // expression can be simplified and use for_each expression
271+
tokenDynamic = hcl.TokensFromString(collectionExpr)
272+
}
273+
resourceb.RemoveBlock(d.block)
274+
return tokenDynamic, nil
275+
}
276+
277+
func extractTagsLabelsIndividual(resourceb *hclwrite.Body, name string) (hclwrite.Tokens, error) {
278+
var (
279+
file = hclwrite.NewEmptyFile()
280+
fileb = file.Body()
281+
found = false
282+
)
261283
for {
262284
block := resourceb.FirstMatchingBlock(name, nil)
263285
if block == nil {
@@ -266,25 +288,16 @@ func fillTagsLabelsOpt(resourceb *hclwrite.Body, name string) error {
266288
key := block.Body().GetAttribute(nKey)
267289
value := block.Body().GetAttribute(nValue)
268290
if key == nil || value == nil {
269-
return fmt.Errorf("%s: %s or %s not found", name, nKey, nValue)
291+
return nil, fmt.Errorf("%s: %s or %s not found", name, nKey, nValue)
270292
}
271293
setKeyValue(fileb, key, value)
272294
resourceb.RemoveBlock(block)
273-
foundIndividual = true
295+
found = true
274296
}
275-
276-
if foundIndividual && tokenDynamic != nil {
277-
resourceb.SetAttributeRaw(name, hcl.TokensMerge(tokenDynamic, hcl.TokensObject(fileb)))
278-
return nil
279-
}
280-
281-
if foundIndividual {
282-
resourceb.SetAttributeRaw(name, hcl.TokensObject(fileb))
283-
}
284-
if tokenDynamic != nil {
285-
resourceb.SetAttributeRaw(name, tokenDynamic)
297+
if !found {
298+
return nil, nil
286299
}
287-
return nil
300+
return hcl.TokensObject(fileb), nil
288301
}
289302

290303
func fillBlockOpt(resourceb *hclwrite.Body, name string) {

internal/hcl/hcl.go

Lines changed: 62 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -79,22 +79,14 @@ func GetAttrString(attr *hclwrite.Attribute, errPrefix string) (string, error) {
7979

8080
// TokensArray creates an array of objects.
8181
func TokensArray(bodies []*hclwrite.Body) hclwrite.Tokens {
82-
ret := hclwrite.Tokens{
83-
{Type: hclsyntax.TokenOBrack, Bytes: []byte("[")},
84-
{Type: hclsyntax.TokenNewline, Bytes: []byte("\n")},
85-
}
82+
ret := hclwrite.Tokens{tokenNewLine}
83+
tokens := make([]hclwrite.Tokens, 0)
8684
for i := range bodies {
87-
ret = append(ret, TokensObject(bodies[i])...)
88-
if i < len(bodies)-1 {
89-
ret = append(ret,
90-
&hclwrite.Token{Type: hclsyntax.TokenComma, Bytes: []byte(",")},
91-
&hclwrite.Token{Type: hclsyntax.TokenNewline, Bytes: []byte("\n")})
92-
}
85+
tokens = append(tokens, TokensObject(bodies[i]))
9386
}
94-
ret = append(ret,
95-
&hclwrite.Token{Type: hclsyntax.TokenNewline, Bytes: []byte("\n")},
96-
&hclwrite.Token{Type: hclsyntax.TokenCBrack, Bytes: []byte("]")})
97-
return ret
87+
ret = append(ret, joinTokens(tokens...)...)
88+
ret = append(ret, tokenNewLine)
89+
return encloseBrackets(ret)
9890
}
9991

10092
// TokensArraySingle creates an array of one object.
@@ -104,49 +96,31 @@ func TokensArraySingle(body *hclwrite.Body) hclwrite.Tokens {
10496

10597
// TokensObject creates an object.
10698
func TokensObject(body *hclwrite.Body) hclwrite.Tokens {
107-
tokens := RemoveLeadingNewline(body.BuildTokens(nil))
108-
ret := hclwrite.Tokens{
109-
{Type: hclsyntax.TokenOBrace, Bytes: []byte("{")},
110-
{Type: hclsyntax.TokenNewline, Bytes: []byte("\n")},
111-
}
112-
ret = append(ret, tokens...)
113-
ret = append(ret,
114-
&hclwrite.Token{Type: hclsyntax.TokenCBrace, Bytes: []byte("}")})
115-
return ret
99+
tokens := hclwrite.Tokens{tokenNewLine}
100+
tokens = append(tokens, RemoveLeadingNewline(body.BuildTokens(nil))...)
101+
return encloseBraces(tokens)
116102
}
117103

118-
// TokensObjectFromString creates an object with a string, which normally contains an expression.
119-
func TokensObjectFromString(expr string) hclwrite.Tokens {
120-
return hclwrite.Tokens{
121-
{Type: hclsyntax.TokenOBrace, Bytes: []byte("{")},
122-
{Type: hclsyntax.TokenNewline, Bytes: []byte("\n")},
123-
{Type: hclsyntax.TokenIdent, Bytes: []byte(expr)},
124-
{Type: hclsyntax.TokenNewline, Bytes: []byte("\n")},
125-
&hclwrite.Token{Type: hclsyntax.TokenCBrace, Bytes: []byte("}")},
126-
}
104+
// TokensFromString creates the tokens for an expression provided as a string.
105+
func TokensFromString(expr string) hclwrite.Tokens {
106+
return hclwrite.Tokens{{Type: hclsyntax.TokenIdent, Bytes: []byte(expr)}}
127107
}
128108

129-
func TokensFromString(expr string) hclwrite.Tokens {
130-
return hclwrite.Tokens{
131-
{Type: hclsyntax.TokenIdent, Bytes: []byte(expr)},
132-
}
109+
// TokensObjectFromExpr creates an object with an expression.
110+
func TokensObjectFromExpr(expr string) hclwrite.Tokens {
111+
tokens := hclwrite.Tokens{tokenNewLine}
112+
tokens = append(tokens, TokensFromString(expr)...)
113+
tokens = append(tokens, tokenNewLine)
114+
return encloseBraces(tokens)
133115
}
134116

135-
func TokensMerge(t1, t2 hclwrite.Tokens) hclwrite.Tokens {
136-
ret := hclwrite.Tokens{
137-
{Type: hclsyntax.TokenIdent, Bytes: []byte("merge")},
138-
{Type: hclsyntax.TokenOParen, Bytes: []byte("(")},
139-
{Type: hclsyntax.TokenNewline, Bytes: []byte("\n")},
140-
}
141-
ret = append(ret, t1...)
142-
ret = append(ret,
143-
&hclwrite.Token{Type: hclsyntax.TokenComma, Bytes: []byte(",")},
144-
&hclwrite.Token{Type: hclsyntax.TokenNewline, Bytes: []byte("\n")})
145-
ret = append(ret, t2...)
146-
ret = append(ret,
147-
&hclwrite.Token{Type: hclsyntax.TokenNewline, Bytes: []byte("\n")},
148-
&hclwrite.Token{Type: hclsyntax.TokenCParen, Bytes: []byte(")")})
149-
return ret
117+
// TokensFuncMerge created the tokens for the HCL merge function.
118+
func TokensFuncMerge(tokens ...hclwrite.Tokens) hclwrite.Tokens {
119+
params := hclwrite.Tokens{tokenNewLine}
120+
params = append(params, joinTokens(tokens...)...)
121+
params = append(params, tokenNewLine)
122+
ret := hclwrite.Tokens{{Type: hclsyntax.TokenIdent, Bytes: []byte("merge")}}
123+
return append(ret, encloseParens(params)...)
150124
}
151125

152126
// RemoveLeadingNewline removes the first newline if it exists to make the output prettier.
@@ -173,3 +147,40 @@ func GetParser(config []byte) (*hclwrite.File, error) {
173147
}
174148
return parser, nil
175149
}
150+
151+
var tokenNewLine = &hclwrite.Token{Type: hclsyntax.TokenNewline, Bytes: []byte("\n")}
152+
153+
// joinTokens joins multiple tokens with commas and newlines.
154+
func joinTokens(tokens ...hclwrite.Tokens) hclwrite.Tokens {
155+
ret := hclwrite.Tokens{}
156+
for i := range tokens {
157+
ret = append(ret, tokens[i]...)
158+
if i < len(tokens)-1 {
159+
ret = append(ret,
160+
&hclwrite.Token{Type: hclsyntax.TokenComma, Bytes: []byte(",")},
161+
tokenNewLine)
162+
}
163+
}
164+
return ret
165+
}
166+
167+
// encloseParens encloses tokens with parentheses, ( ).
168+
func encloseParens(tokens hclwrite.Tokens) hclwrite.Tokens {
169+
ret := hclwrite.Tokens{{Type: hclsyntax.TokenOParen, Bytes: []byte("(")}}
170+
ret = append(ret, tokens...)
171+
return append(ret, &hclwrite.Token{Type: hclsyntax.TokenCParen, Bytes: []byte(")")})
172+
}
173+
174+
// encloseBraces encloses tokens with curly braces, { }.
175+
func encloseBraces(tokens hclwrite.Tokens) hclwrite.Tokens {
176+
ret := hclwrite.Tokens{{Type: hclsyntax.TokenOBrace, Bytes: []byte("{")}}
177+
ret = append(ret, tokens...)
178+
return append(ret, &hclwrite.Token{Type: hclsyntax.TokenCBrace, Bytes: []byte("}")})
179+
}
180+
181+
// encloseBrackets encloses tokens with square brackets, [ ].
182+
func encloseBrackets(tokens hclwrite.Tokens) hclwrite.Tokens {
183+
ret := hclwrite.Tokens{{Type: hclsyntax.TokenOBrack, Bytes: []byte("[")}}
184+
ret = append(ret, tokens...)
185+
return append(ret, &hclwrite.Token{Type: hclsyntax.TokenCBrack, Bytes: []byte("]")})
186+
}

0 commit comments

Comments
 (0)