Skip to content

Commit

Permalink
hcl2: Use the actual string snippet as it appears from undefined
Browse files Browse the repository at this point in the history
With the updated undefined variable code, we attempt to pick the text of
`${....}` verbatim from the hcl body. Previously, we'd attempt to
regenerate the string from the AST and pray it matches input; the
generation is lossy, as the same AST can represent multiple variations
(e.g. `${v.0}` and `${v[0]}` have the same HCLv2 AST). In this change,
we attempt to go back to the hcl2 source and find the string snippet
corresponding to the variable reference.
  • Loading branch information
Mahmood Ali committed Apr 7, 2021
1 parent e488493 commit f4b62ea
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
1 change: 1 addition & 0 deletions jobspec2/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,7 @@ func TestParse_UndefinedVariables(t *testing.T) {
"foo-${attr.network.dev-us-east1-relay-vpc.external-ip.0}",
`${env["BLAH"]}`,
`${mixed-indexing.0[3]["FOO"].5}`,
`with spaces ${ root. field[ "FOO"].5 }`,
}

for _, c := range cases {
Expand Down
23 changes: 21 additions & 2 deletions jobspec2/types.config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package jobspec2

import (
"bytes"
"fmt"
"strings"

Expand Down Expand Up @@ -308,8 +309,26 @@ func (c *jobConfig) EvalContext() *hcl.EvalContext {
inputVariablesAccessor: cty.ObjectVal(vars),
localsAccessor: cty.ObjectVal(locals),
},
UnknownVariable: func(expr string) (cty.Value, error) {
v := "${" + expr + "}"
UndefinedVariable: func(t hcl.Traversal) (cty.Value, hcl.Diagnostics) {
body := c.ParseConfig.Body
start := t.SourceRange().Start.Byte
end := t.SourceRange().End.Byte

v := string(body[start:end])
if i := bytes.IndexByte(body[end:], '}'); i != -1 {
v += string(body[end : end+i+1])
} else {
// fallback for unexpected cases
v += "}"
}

if i := bytes.LastIndex(body[:start], []byte("${")); i != 0 {
v = string(body[i:start]) + v
} else {
// fallback for unexpected cases
v = "${" + v
}

return cty.StringVal(v), nil
},
}
Expand Down

0 comments on commit f4b62ea

Please sign in to comment.