Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"go generate" multiline command

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

like image 733
John White Avatar asked Apr 09 '19 18:04

John White


2 Answers

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

like image 104
Никифор Серяков Avatar answered Nov 15 '22 04:11

Никифор Серяков


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
// ...
like image 33
YenForYang Avatar answered Nov 15 '22 03:11

YenForYang