hcl icon indicating copy to clipboard operation
hcl copied to clipboard

Can't find instructions for inline comments for hclwrite

Open nikatjef opened this issue 4 years ago • 3 comments

Greetings,

Would not be surprised if this is me, but I am unable to figure out how to add an inline comment using the hclwrite. For example, I have the following code;

		f := hclwrite.NewEmptyFile()
		rootBody := f.Body()
		rootBody.SetAttributeValue("name", cty.StringVal(config.Name))
		rootBody.AppendNewline()
		rootBody.SetAttributeValue("mode", cty.StringVal("router"))
		rootBody.AppendNewline()
		log.Printf("%s", f.Bytes())

Which will give me the following output;

name = "gagent.example.org"

mode = "router"

What I am trying to do is add a comment so the actual output would be something like the following;

name = "gagent.example.org"

/*
 * There are three modes of operation;
 *   client == Clients read a local agent file and send it to a router
 *   router == Routers route agent files to workers for operation
 *   worker == Workers process agent files
 */
mode = "router"

Again, I would not be surprised if I am just missing something simple, but any help would be appreciated it.

nikatjef avatar Apr 05 '21 14:04 nikatjef

Hi @nikatjef,

The Body type has a method AppendUnstructuredTokens for inserting extra tokens that are not nested blocks or arguments. This is similar to the AppendNewline method you're already using in that it just appends tokens to the end of the body, and so to get a result like you showed you'd need to call it just before SetAttributeValue("mode", ...).

The token type for a comment is hclsyntax.TokenComment, and the content of that token should be the entire comment, including all of the punctuation, and including a trailing newline for comments that end with one. Due to how the HCL scanner processes comments, the newline at the end of a comment typically replaces a naked newline at that location -- in a sense, a comment with a newline at the end is just treated as a newline token -- so I'd include the \n in the comment and not call AppendNewline after.

You showed a multi-line /* */ comment in your example, which would be a single token. Common HCL-based languages like Terraform's typically prefer single-line comments starting with # by convention, in which case the expected token stream for those would be a separate token for each line, each one ending with a newline byte \n.

I must confess that I've not specifically tried to generate a multi-line comment like that before as far as I can remember, so I'd be interested to hear how that turns out.

apparentlymart avatar Apr 15 '21 22:04 apparentlymart

this is how i am doing. you can write a function to generate multi line comment

newBody.AppendUnstructuredTokens(hclwrite.TokensForTraversal(hcl.Traversal{ hcl.TraverseRoot{ Name: CommentGenerator("comment"), }, }))

ssingh-humana avatar Nov 16 '21 18:11 ssingh-humana

The following worked nicely for me to create multiline comments

w := hclwrite.NewFile()
rootBody := w.Body()

// Add a comment to the file
comment := hclwrite.Tokens{
	&hclwrite.Token{
		Type:         hclsyntax.TokenComment,
		Bytes:        []byte("#This is a line.\n#This is another line\n"),
		SpacesBefore: 0,
	},
}
rootBody.AppendUnstructuredTokens(comment)

avestuk avatar Oct 06 '22 19:10 avestuk