summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Atkins <mart@degeneration.co.uk>2024-05-08 17:55:39 -0700
committerMartin Atkins <mart@degeneration.co.uk>2024-05-09 11:32:15 -0700
commit318bbfebb5e1eeea09765b1edb1aec303f75a268 (patch)
tree01a33e63c36b7d2f54482c1cd87bcd136096a4dd
parent9a64c17c75059d9c8f5d94f2265c00026ac48781 (diff)
hcldec: Allow body-derived values to be marked
Similar to the previously-added UnknownBody, the new optional interface MarkedBody allows hcl.Body implementations to suggest a set of marks that ought to be applied to any value that's generated to represent the content of that body. The dynblock extension then uses this to get hcldec to mark the whole object representing any block that was generated by a dynamic block whose for_each was marked, for a better representation of the fact that a block's existence was decided based on a marked value.
-rw-r--r--ext/dynblock/expand_body.go5
-rw-r--r--ext/dynblock/expand_body_test.go2
-rw-r--r--go.mod2
-rw-r--r--go.sum4
-rw-r--r--hcldec/spec.go19
5 files changed, 30 insertions, 2 deletions
diff --git a/ext/dynblock/expand_body.go b/ext/dynblock/expand_body.go
index e630f18..2cafae5 100644
--- a/ext/dynblock/expand_body.go
+++ b/ext/dynblock/expand_body.go
@@ -270,3 +270,8 @@ func (b *expandBody) JustAttributes() (hcl.Attributes, hcl.Diagnostics) {
func (b *expandBody) MissingItemRange() hcl.Range {
return b.original.MissingItemRange()
}
+
+// hcldec.MarkedBody impl
+func (b *expandBody) BodyValueMarks() cty.ValueMarks {
+ return b.valueMarks
+}
diff --git a/ext/dynblock/expand_body_test.go b/ext/dynblock/expand_body_test.go
index 3b245ee..0941f29 100644
--- a/ext/dynblock/expand_body_test.go
+++ b/ext/dynblock/expand_body_test.go
@@ -762,7 +762,7 @@ func TestExpandMarkedForEach(t *testing.T) {
cty.ObjectVal(map[string]cty.Value{
"val0": cty.StringVal("static c 1").Mark("boop"),
"val1": cty.StringVal("hey").Mark("boop"),
- }),
+ }).Mark("boop"),
})
got, diags := hcldec.Decode(dynBody, decSpec, nil)
if diags.HasErrors() {
diff --git a/go.mod b/go.mod
index d9d4da4..56c414f 100644
--- a/go.mod
+++ b/go.mod
@@ -11,7 +11,7 @@ require (
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7
github.com/spf13/pflag v1.0.2
github.com/zclconf/go-cty v1.13.0
- github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b
+ github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940
golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167
golang.org/x/tools v0.6.0
)
diff --git a/go.sum b/go.sum
index 08ed23e..53611d8 100644
--- a/go.sum
+++ b/go.sum
@@ -27,6 +27,10 @@ github.com/zclconf/go-cty v1.13.0 h1:It5dfKTTZHe9aeppbNOda3mN7Ag7sg6QkBNm6TkyFa0
github.com/zclconf/go-cty v1.13.0/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0=
github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b h1:FosyBZYxY34Wul7O/MSKey3txpPYyCqVO5ZyceuQJEI=
github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8=
+github.com/zclconf/go-cty-debug v0.0.0-20240417160409-8c45e122ae1a h1:/o/Emn22dZIQ7AhyA0aLOKo528WG/WRAM5tqzIoQIOs=
+github.com/zclconf/go-cty-debug v0.0.0-20240417160409-8c45e122ae1a/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM=
+github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo=
+github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM=
golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167 h1:O8uGbHCqlTp2P6QJSLmCojM4mN6UemYv8K+dCnmHmu0=
golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
diff --git a/hcldec/spec.go b/hcldec/spec.go
index 2bebc43..b07a553 100644
--- a/hcldec/spec.go
+++ b/hcldec/spec.go
@@ -73,6 +73,12 @@ type UnknownBody interface {
Unknown() bool
}
+// MarkedBody can be optionally implemented by an hcl.Body instance to
+// indicate that a value created from it ought to be marked.
+type MarkedBody interface {
+ BodyValueMarks() cty.ValueMarks
+}
+
func (s ObjectSpec) visitSameBodyChildren(cb visitFunc) {
for _, c := range s {
cb(c)
@@ -473,6 +479,7 @@ func (s *BlockListSpec) decode(content *hcl.BodyContent, blockLabels []blockLabe
val, _, childDiags := decode(childBlock.Body, labelsForBlock(childBlock), ctx, s.Nested, false)
diags = append(diags, childDiags...)
+ val = prepareBodyVal(val, childBlock.Body)
if u, ok := childBlock.Body.(UnknownBody); ok {
if u.Unknown() {
@@ -635,6 +642,7 @@ func (s *BlockTupleSpec) decode(content *hcl.BodyContent, blockLabels []blockLab
val, _, childDiags := decode(childBlock.Body, labelsForBlock(childBlock), ctx, s.Nested, false)
diags = append(diags, childDiags...)
+ val = prepareBodyVal(val, childBlock.Body)
if u, ok := childBlock.Body.(UnknownBody); ok {
if u.Unknown() {
@@ -758,6 +766,7 @@ func (s *BlockSetSpec) decode(content *hcl.BodyContent, blockLabels []blockLabel
val, _, childDiags := decode(childBlock.Body, labelsForBlock(childBlock), ctx, s.Nested, false)
diags = append(diags, childDiags...)
+ val = prepareBodyVal(val, childBlock.Body)
if u, ok := childBlock.Body.(UnknownBody); ok {
if u.Unknown() {
@@ -928,6 +937,7 @@ func (s *BlockMapSpec) decode(content *hcl.BodyContent, blockLabels []blockLabel
childLabels := labelsForBlock(childBlock)
val, _, childDiags := decode(childBlock.Body, childLabels[len(s.LabelNames):], ctx, s.Nested, false)
+ val = prepareBodyVal(val, childBlock.Body)
targetMap := elems
for _, key := range childBlock.Labels[:len(s.LabelNames)-1] {
if _, exists := targetMap[key]; !exists {
@@ -1082,6 +1092,7 @@ func (s *BlockObjectSpec) decode(content *hcl.BodyContent, blockLabels []blockLa
childLabels := labelsForBlock(childBlock)
val, _, childDiags := decode(childBlock.Body, childLabels[len(s.LabelNames):], ctx, s.Nested, false)
+ val = prepareBodyVal(val, childBlock.Body)
targetMap := elems
for _, key := range childBlock.Labels[:len(s.LabelNames)-1] {
if _, exists := targetMap[key]; !exists {
@@ -1720,3 +1731,11 @@ func (s noopSpec) sourceRange(content *hcl.BodyContent, blockLabels []blockLabel
Filename: "noopSpec",
}
}
+
+func prepareBodyVal(decodeResult cty.Value, body hcl.Body) cty.Value {
+ if m, ok := body.(MarkedBody); ok {
+ marks := m.BodyValueMarks()
+ return decodeResult.WithMarks(marks)
+ }
+ return decodeResult
+}