-
Notifications
You must be signed in to change notification settings - Fork 1
/
hcl_block.go
121 lines (111 loc) · 2.85 KB
/
hcl_block.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package golden
import (
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/hashicorp/hcl/v2/hclwrite"
"github.com/zclconf/go-cty/cty"
)
type HclBlock struct {
*hclsyntax.Block
wb *hclwrite.Block
*ForEach
attributes map[string]*HclAttribute
blocks []*HclBlock
}
func NewHclBlock(rb *hclsyntax.Block, wb *hclwrite.Block, each *ForEach) *HclBlock {
hb := &HclBlock{
Block: rb,
wb: wb,
ForEach: each,
attributes: make(map[string]*HclAttribute),
}
for n, ra := range rb.Body.Attributes {
hb.attributes[n] = NewHclAttribute(ra, wb.Body().Attributes()[n])
}
for i, nrb := range rb.Body.Blocks {
hb.blocks = append(hb.blocks, NewHclBlock(nrb, wb.Body().Blocks()[i] /*TODO: dynamic support in the future*/, nil))
}
return hb
}
func (hb *HclBlock) Attributes() map[string]*HclAttribute {
return hb.attributes
}
func (hb *HclBlock) NestedBlocks() []*HclBlock {
return hb.blocks
}
type ForEach struct {
key cty.Value
value cty.Value
}
func NewForEach(key, value cty.Value) *ForEach {
return &ForEach{
key: key,
value: value,
}
}
func AsHclBlocks(syntaxBlocks hclsyntax.Blocks, writeBlocks []*hclwrite.Block) []*HclBlock {
var blocks []*HclBlock
for i, b := range syntaxBlocks {
var rbs = readRawHclSyntaxBlock(b)
var wbs = readRawHclWriteBlock(writeBlocks[i])
for i, hb := range rbs {
blocks = append(blocks, NewHclBlock(hb, wbs[i], nil))
}
}
return blocks
}
func readRawHclSyntaxBlock(b *hclsyntax.Block) []*hclsyntax.Block {
switch b.Type {
case "locals":
{
var newBlocks []*hclsyntax.Block
for _, attr := range b.Body.Attributes {
newBlocks = append(newBlocks, &hclsyntax.Block{
Type: "local",
Labels: []string{"", attr.Name},
Body: &hclsyntax.Body{
Attributes: map[string]*hclsyntax.Attribute{
"value": {
Name: "value",
Expr: attr.Expr,
SrcRange: attr.SrcRange,
NameRange: attr.NameRange,
EqualsRange: attr.EqualsRange,
},
},
SrcRange: attr.NameRange,
EndRange: attr.SrcRange,
},
})
}
return newBlocks
}
case "variable":
{
return []*hclsyntax.Block{
{
Type: "variable",
Labels: append([]string{""}, b.Labels...),
Body: b.Body,
TypeRange: b.TypeRange,
LabelRanges: b.LabelRanges,
OpenBraceRange: b.OpenBraceRange,
CloseBraceRange: b.CloseBraceRange,
},
}
}
default:
return []*hclsyntax.Block{b}
}
}
func readRawHclWriteBlock(b *hclwrite.Block) []*hclwrite.Block {
if b.Type() != "locals" {
return []*hclwrite.Block{b}
}
var newBlocks []*hclwrite.Block
for n, attr := range b.Body().Attributes() {
nb := hclwrite.NewBlock("local", []string{"", n})
nb.Body().SetAttributeRaw("value", attr.Expr().BuildTokens(hclwrite.Tokens{}))
newBlocks = append(newBlocks, nb)
}
return newBlocks
}