Skip to content

Commit 4997e11

Browse files
authored
Merge pull request #404 from hashicorp/alisdair/pass-marks-through-expression-templates
hclsyntax: Pass marks through template expressions
2 parents bf0a7fe + 876b423 commit 4997e11

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

hclsyntax/expression_template.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ func (e *TemplateExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics)
2626
var diags hcl.Diagnostics
2727
isKnown := true
2828

29+
// Maintain a set of marks for values used in the template
30+
marks := make(cty.ValueMarks)
31+
2932
for _, part := range e.Parts {
3033
partVal, partDiags := part.Value(ctx)
3134
diags = append(diags, partDiags...)
@@ -71,14 +74,24 @@ func (e *TemplateExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics)
7174
continue
7275
}
7376

74-
buf.WriteString(strVal.AsString())
77+
// Unmark the part and merge its marks into the set
78+
unmarked, partMarks := strVal.Unmark()
79+
for k, v := range partMarks {
80+
marks[k] = v
81+
}
82+
83+
buf.WriteString(unmarked.AsString())
7584
}
7685

86+
var ret cty.Value
7787
if !isKnown {
78-
return cty.UnknownVal(cty.String), diags
88+
ret = cty.UnknownVal(cty.String)
89+
} else {
90+
ret = cty.StringVal(buf.String())
7991
}
8092

81-
return cty.StringVal(buf.String()), diags
93+
// Apply the full set of marks to the returned value
94+
return ret.WithMarks(marks), diags
8295
}
8396

8497
func (e *TemplateExpr) Range() hcl.Range {

hclsyntax/expression_template_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,27 @@ trim`,
283283
cty.UnknownVal(cty.String),
284284
1, // Unexpected endfor directive
285285
},
286+
{ // marks from uninterpolated values are ignored
287+
`hello%{ if false } ${target}%{ endif }`,
288+
&hcl.EvalContext{
289+
Variables: map[string]cty.Value{
290+
"target": cty.StringVal("world").WithMarks(cty.NewValueMarks("sensitive")),
291+
},
292+
},
293+
cty.StringVal("hello"),
294+
0,
295+
},
296+
{ // marks from interpolated values are passed through
297+
`${greeting} ${target}`,
298+
&hcl.EvalContext{
299+
Variables: map[string]cty.Value{
300+
"greeting": cty.StringVal("hello").WithMarks(cty.NewValueMarks("english")),
301+
"target": cty.StringVal("world").WithMarks(cty.NewValueMarks("sensitive")),
302+
},
303+
},
304+
cty.StringVal("hello world").WithMarks(cty.NewValueMarks("english", "sensitive")),
305+
0,
306+
},
286307
}
287308

288309
for _, test := range tests {

0 commit comments

Comments
 (0)