diff options
author | Nathan Dench <ndenc2@gmail.com> | 2019-05-24 15:16:44 +1000 |
---|---|---|
committer | Nathan Dench <ndenc2@gmail.com> | 2019-05-24 15:16:44 +1000 |
commit | 107c1cdb09c575aa2f61d97f48d8587eb6bada4c (patch) | |
tree | ca7d008643efc555c388baeaf1d986e0b6b3e28c /vendor/github.com/hashicorp/terraform/configs/module_merge_body.go | |
parent | 844b5a68d8af4791755b8f0ad293cc99f5959183 (diff) | |
download | terraform-provider-statuscake-107c1cdb09c575aa2f61d97f48d8587eb6bada4c.tar.gz terraform-provider-statuscake-107c1cdb09c575aa2f61d97f48d8587eb6bada4c.tar.zst terraform-provider-statuscake-107c1cdb09c575aa2f61d97f48d8587eb6bada4c.zip |
Upgrade to 0.12
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/configs/module_merge_body.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/configs/module_merge_body.go | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/configs/module_merge_body.go b/vendor/github.com/hashicorp/terraform/configs/module_merge_body.go new file mode 100644 index 0000000..0ed561e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/configs/module_merge_body.go | |||
@@ -0,0 +1,143 @@ | |||
1 | package configs | ||
2 | |||
3 | import ( | ||
4 | "github.com/hashicorp/hcl2/hcl" | ||
5 | ) | ||
6 | |||
7 | // MergeBodies creates a new HCL body that contains a combination of the | ||
8 | // given base and override bodies. Attributes and blocks defined in the | ||
9 | // override body take precedence over those of the same name defined in | ||
10 | // the base body. | ||
11 | // | ||
12 | // If any block of a particular type appears in "override" then it will | ||
13 | // replace _all_ of the blocks of the same type in "base" in the new | ||
14 | // body. | ||
15 | func MergeBodies(base, override hcl.Body) hcl.Body { | ||
16 | return mergeBody{ | ||
17 | Base: base, | ||
18 | Override: override, | ||
19 | } | ||
20 | } | ||
21 | |||
22 | // mergeBody is a hcl.Body implementation that wraps a pair of other bodies | ||
23 | // and allows attributes and blocks within the override to take precedence | ||
24 | // over those defined in the base body. | ||
25 | // | ||
26 | // This is used to deal with dynamically-processed bodies in Module.mergeFile. | ||
27 | // It uses a shallow-only merging strategy where direct attributes defined | ||
28 | // in Override will override attributes of the same name in Base, while any | ||
29 | // blocks defined in Override will hide all blocks of the same type in Base. | ||
30 | // | ||
31 | // This cannot possibly "do the right thing" in all cases, because we don't | ||
32 | // have enough information about user intent. However, this behavior is intended | ||
33 | // to be reasonable for simple overriding use-cases. | ||
34 | type mergeBody struct { | ||
35 | Base hcl.Body | ||
36 | Override hcl.Body | ||
37 | } | ||
38 | |||
39 | var _ hcl.Body = mergeBody{} | ||
40 | |||
41 | func (b mergeBody) Content(schema *hcl.BodySchema) (*hcl.BodyContent, hcl.Diagnostics) { | ||
42 | var diags hcl.Diagnostics | ||
43 | baseSchema := schemaWithDynamic(schema) | ||
44 | overrideSchema := schemaWithDynamic(schemaForOverrides(schema)) | ||
45 | |||
46 | baseContent, _, cDiags := b.Base.PartialContent(baseSchema) | ||
47 | diags = append(diags, cDiags...) | ||
48 | overrideContent, _, cDiags := b.Override.PartialContent(overrideSchema) | ||
49 | diags = append(diags, cDiags...) | ||
50 | |||
51 | content := b.prepareContent(baseContent, overrideContent) | ||
52 | |||
53 | return content, diags | ||
54 | } | ||
55 | |||
56 | func (b mergeBody) PartialContent(schema *hcl.BodySchema) (*hcl.BodyContent, hcl.Body, hcl.Diagnostics) { | ||
57 | var diags hcl.Diagnostics | ||
58 | baseSchema := schemaWithDynamic(schema) | ||
59 | overrideSchema := schemaWithDynamic(schemaForOverrides(schema)) | ||
60 | |||
61 | baseContent, baseRemain, cDiags := b.Base.PartialContent(baseSchema) | ||
62 | diags = append(diags, cDiags...) | ||
63 | overrideContent, overrideRemain, cDiags := b.Override.PartialContent(overrideSchema) | ||
64 | diags = append(diags, cDiags...) | ||
65 | |||
66 | content := b.prepareContent(baseContent, overrideContent) | ||
67 | |||
68 | remain := MergeBodies(baseRemain, overrideRemain) | ||
69 | |||
70 | return content, remain, diags | ||
71 | } | ||
72 | |||
73 | func (b mergeBody) prepareContent(base *hcl.BodyContent, override *hcl.BodyContent) *hcl.BodyContent { | ||
74 | content := &hcl.BodyContent{ | ||
75 | Attributes: make(hcl.Attributes), | ||
76 | } | ||
77 | |||
78 | // For attributes we just assign from each map in turn and let the override | ||
79 | // map clobber any matching entries from base. | ||
80 | for k, a := range base.Attributes { | ||
81 | content.Attributes[k] = a | ||
82 | } | ||
83 | for k, a := range override.Attributes { | ||
84 | content.Attributes[k] = a | ||
85 | } | ||
86 | |||
87 | // Things are a little more interesting for blocks because they arrive | ||
88 | // as a flat list. Our merging semantics call for us to suppress blocks | ||
89 | // from base if at least one block of the same type appears in override. | ||
90 | // We explicitly do not try to correlate and deeply merge nested blocks, | ||
91 | // since we don't have enough context here to infer user intent. | ||
92 | |||
93 | overriddenBlockTypes := make(map[string]bool) | ||
94 | for _, block := range override.Blocks { | ||
95 | if block.Type == "dynamic" { | ||
96 | overriddenBlockTypes[block.Labels[0]] = true | ||
97 | continue | ||
98 | } | ||
99 | overriddenBlockTypes[block.Type] = true | ||
100 | } | ||
101 | for _, block := range base.Blocks { | ||
102 | // We skip over dynamic blocks whose type label is an overridden type | ||
103 | // but note that below we do still leave them as dynamic blocks in | ||
104 | // the result because expanding the dynamic blocks that are left is | ||
105 | // done much later during the core graph walks, where we can safely | ||
106 | // evaluate the expressions. | ||
107 | if block.Type == "dynamic" && overriddenBlockTypes[block.Labels[0]] { | ||
108 | continue | ||
109 | } | ||
110 | if overriddenBlockTypes[block.Type] { | ||
111 | continue | ||
112 | } | ||
113 | content.Blocks = append(content.Blocks, block) | ||
114 | } | ||
115 | for _, block := range override.Blocks { | ||
116 | content.Blocks = append(content.Blocks, block) | ||
117 | } | ||
118 | |||
119 | return content | ||
120 | } | ||
121 | |||
122 | func (b mergeBody) JustAttributes() (hcl.Attributes, hcl.Diagnostics) { | ||
123 | var diags hcl.Diagnostics | ||
124 | ret := make(hcl.Attributes) | ||
125 | |||
126 | baseAttrs, aDiags := b.Base.JustAttributes() | ||
127 | diags = append(diags, aDiags...) | ||
128 | overrideAttrs, aDiags := b.Override.JustAttributes() | ||
129 | diags = append(diags, aDiags...) | ||
130 | |||
131 | for k, a := range baseAttrs { | ||
132 | ret[k] = a | ||
133 | } | ||
134 | for k, a := range overrideAttrs { | ||
135 | ret[k] = a | ||
136 | } | ||
137 | |||
138 | return ret, diags | ||
139 | } | ||
140 | |||
141 | func (b mergeBody) MissingItemRange() hcl.Range { | ||
142 | return b.Base.MissingItemRange() | ||
143 | } | ||