diff --git a/jobspec2/parse_test.go b/jobspec2/parse_test.go index 17492d6abfd9..a815cd0da9e7 100644 --- a/jobspec2/parse_test.go +++ b/jobspec2/parse_test.go @@ -873,6 +873,21 @@ func TestParse_UndefinedVariables(t *testing.T) { require.Equal(t, c, *job.Region) }) } + + t.Run("unquoted", func(t *testing.T) { + hcl := `job "example" { + region = meta.mytest +}` + + job, err := ParseWithConfig(&ParseConfig{ + Path: "input.hcl", + Body: []byte(hcl), + }) + require.NoError(t, err) + + require.Equal(t, "${meta.mytest}", *job.Region) + + }) } func TestParseServiceCheck(t *testing.T) { diff --git a/jobspec2/types.config.go b/jobspec2/types.config.go index 12bb58f344ae..28e059172142 100644 --- a/jobspec2/types.config.go +++ b/jobspec2/types.config.go @@ -1,7 +1,6 @@ package jobspec2 import ( - "bytes" "fmt" "strings" @@ -315,18 +314,32 @@ func (c *jobConfig) EvalContext() *hcl.EvalContext { 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 += "}" + + // find the start of inclusing "${..}" if it's inclused in one; otherwise, wrap it in one + isBracketed := false + for i := start - 1; i >= 1; i-- { + if body[i] == '{' && body[i-1] == '$' { + isBracketed = true + v = string(body[i-1:start]) + v + break + } else if body[i] != ' ' { + break + } } - if i := bytes.LastIndex(body[:start], []byte("${")); i != 0 { - v = string(body[i:start]) + v + if isBracketed { + for i := end + 1; i < len(body); i++ { + if body[i] == '}' { + v += string(body[end:i]) + } else if body[i] != ' ' { + // unexpected! + v += "}" + break + } + } + } else { - // fallback for unexpected cases - v = "${" + v + v = "${" + v + "}" } return cty.StringVal(v), nil