Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failed to parse a heredoc expression as it is #441

Open
wata727 opened this issue Jan 5, 2021 · 1 comment
Open

Failed to parse a heredoc expression as it is #441

wata727 opened this issue Jan 5, 2021 · 1 comment

Comments

@wata727
Copy link
Contributor

wata727 commented Jan 5, 2021

HCL Template

foo = <<EOF
{}
EOF

Expected behavior

After parsing the above file as a config, if you take bytes from the range of the "foo" expression (<<EOF\n{}\nEOF) and parse it again as an expression based on its start position and the bytes, you expect to get the expression correctly.

Actual behavior

Failed to parse bytes as an expression. It says "Unterminated template string; No closing marker was found for the string."

Steps to reproduce

Run the following code:

package main

import (
	"fmt"
	"io/ioutil"

	"github.com/hashicorp/hcl/v2"
	"github.com/hashicorp/hcl/v2/hclsyntax"
)

func main() {
	src, err := ioutil.ReadFile("config.hcl")
	if err != nil {
		panic(err)
	}
	file, diags := hclsyntax.ParseConfig(src, "config.hcl", hcl.InitialPos)
	if diags.HasErrors() {
		panic(diags)
	}
	attributes, diags := file.Body.JustAttributes()
	if diags.HasErrors() {
		panic(diags)
	}
	expr := attributes["foo"].Expr

	exprSrc := expr.Range().SliceBytes(src)
	fmt.Println("Source:")
	fmt.Println(string(exprSrc))
	fmt.Print("\n")

	parsedExpr, diags := hclsyntax.ParseExpression(exprSrc, "config.hcl", expr.Range().Start)
	if diags.HasErrors() {
		panic(diags)
	}

	fmt.Printf("original=%#v\n", expr)
	fmt.Printf("parsed=%#v\n", parsedExpr)
}

References

@wata727
Copy link
Contributor Author

wata727 commented Jan 5, 2021

But it's understandable that it fails to parse this. When you retrieve an expression based on the range, the last newline is always lost. This is invalid as heredoc.

<<EOF
{}
EOF
\ No newline at end of file

In addition, I noticed that ParseExpression always parses the bytes in "ignore newlines" mode.

hcl/hclsyntax/public.go

Lines 46 to 48 in 56e58b6

// Bare expressions are always parsed in "ignore newlines" mode, as if
// they were wrapped in parentheses.
parser.PushIncludeNewlines(false)

The problem I want to solve with this issue is that I want to know if I should fix the ParseExpression for this problem or if it's the user's responsibility to always add a newline at the end of the passed bytes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant