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

GoHCL does not support interpolation #615

Open
FLAGLORD opened this issue Jun 25, 2023 · 3 comments
Open

GoHCL does not support interpolation #615

FLAGLORD opened this issue Jun 25, 2023 · 3 comments

Comments

@FLAGLORD
Copy link

FLAGLORD commented Jun 25, 2023

I noticed this issue.
It mentioned that GoHCL only supports static values, and it would convert all string beginning with ${ to $ $${. It brings some problem when using interpolation.

hcl/hclwrite/generate.go

Lines 367 to 372 in 7208bce

case '$', '%':
buf = appendRune(buf, r)
remain := s[i+1:]
if len(remain) > 0 && remain[0] == '{' {
// Double up our template introducer symbol to escape it.
buf = appendRune(buf, r)

Could it support something like \$ to deal with interpolation string? I think it would not corrupt compatibility.

@FLAGLORD
Copy link
Author

FLAGLORD commented Jun 25, 2023

In fact, I am a little confused. If we know that it is a interpolation, why should we escape it?

@FLAGLORD FLAGLORD changed the title GoHCL does not support interplotation GoHCL does not support interpolation Jun 25, 2023
@apparentlymart
Copy link
Member

Hi @FLAGLORD,

I'm not sure I follow what you are referring to, since the summary of the issue talks about gohcl but the code you've linked to is in hclwrite.

However, I think what you are asking amounts to: "why can't hclwrite just assume that if I have ${ in my string then I intend it to be a template interpolation sequence?", and the answer is that if that were true then decoding and re-encoding would be asymmetrical: there's no way for expression evaluation to produce a string template because evaluating string templates into strings is part of the expression evaluation process. Conversely, after evaluation there is no longer any record of the fact that the string originated as a string template: it's just a literal string value. If that string contains ${ then that's because the original string template contained $${ -- the interpolation escape sequence -- and so it's correct for the encoder to reverse that and transform it back to $${ again.

If you want to produce HCL syntax rather than HCL values then gohcl is the wrong level of abstraction for that. The hclwrite API is the appropriate API to use if you want to produce specific syntax; that package is designed to work with the HCL syntax tree instead of with values.

@FLAGLORD
Copy link
Author

Hi @apparentlymart.
Thanks for your rapid and detailed reply.

I want to provide some background information: I hope to generate a HCL syntax file with some existing configuration information. But I found that hclwrite is too low-level, and thus it is flexible but a little tedious. With gohcl, I can define a struct(of course with hcl tags), initialize it and invoke gohcl.EncodeIntoBody() to convert it to hcl.Body. The hclwrite code linked above is actually invoked in the execution of gohcl.EncodeIntoBody().

The symmetry of decoding and re-encoding you mentioned is really a key point, and I roughly got it. But I'm still a little confused. In your example, original string template contained $${ and decoder decodes it to ${, so it is reasonable for encoder to transform it back to ${{. But what if original string template contained ${? Would it be replaced by interpolation in the decodinng process? Is there something like parse instead of eval?

For ASCII escape characters like \t and \n, encoder and decoder really works perfectly. But for interpolation templates, golang actually does not support interpolation syntax like ${ and %{ as they are HCL-specific. Even if decoder decodes ${ to ${ and ${{ to ${{, developers wouldn't gain anything but also wouldn't lose anything, but it provides a way for developers to produce interpolation template.

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

2 participants