"go generate" multiline command
Asked Answered
Y

2

10

I'm trying to use //go:generate to run an external tool before compiling my code, and as I need to pass a certain number of parameters, the line becomes rather long.

It seems that there is no way to write a multiline go:generate command, is it correct? Are there alternative approaches?

Thanks

Yazzie answered 9/4, 2019 at 18:18 Comment(1)
go:generate must be a single line. If your command is too long for your taste you would need to move it to e.g. a shell script, and execute that script via go:generate.Pinball
F
9

There is no way to split go generate command into several lines, but there are some tips.

If you need to run multiple short commands you can write them one by one like the following.

//go:generate echo command A
//go:generate echo command B
//go:generate ls

You also should know that there is not a bash script but a raw command. So the following works not as one may expect.

//go:generate echo something | tr a-z A-Z > into_file
// result in "something | tr a-z A-Z > into_file"

For long or complex commands you should use separate script (or maybe go program) that is called from go:generate comment.

//go:generate sh generate.sh
//go:generate go run generator.go arg-A arg-B

In generator.go you should use build tag to prevent it from normal compilation with other files.

// +build ignore

package main
// ...

The best place to learn go is go sources: https://github.com/golang/go/blob/master/src/runtime/runtime.go#L13

Frank answered 10/4, 2019 at 9:10 Comment(0)
W
5

This is far from an ideal solution, but you could use a directive of the form

//go:generate -command <alias> <command-with-parameters>

The directive above specifies, for the remainder of the current source file only, that <alias> is equivalent to the command <command-with-parameters>.

This method might be useful in your case since you mentioned that you needed to pass a certain number of parameters (I'm assuming lots). You could potentially use it to emulate a single line break. I say single because nested aliases don't work (at least right now).

An example:

//go:generate BAKE "ramen"


  // The above go:generate directive does NOT work, unless:
  //  - You somehow have bake on your path.
  //  - You did a `//go:generate -command BAKE ...`


/* Now, assuming you have a command `kitchen-tools` with lots of possible parameters... */

//go:generate -command BAKE kitchen-tools -appliance=sun -temp=5800K -time=1ns 
//go:generate BAKE -panic=if-burnt -safety=fire_extinguisher,mitts "fresh pizza"


  // The previous //go:generate line runs the following command:
  //  kitchen-tools -appliance=sun -temp=5800K -time=1ns -panic=always -safety=fire_extinguisher,mitts "fresh pizza"

/* BAKE can be used as many times as necessary for the rest of the file. For instance... */

//go:generate BAKE -no-return -unsafe "grand piano"
  

Furthermore, I suggest you use the build tag generate (rather than something like ignore) since the go generate tool sets the build tag generate when it examines your files:

// +build generate

package main
// ...
Week answered 5/8, 2021 at 3:27 Comment(1)
This is really nice for long params in a single command!Trucking

© 2022 - 2024 — McMap. All rights reserved.