go generate with gofmt, replacing variable value

777 views Asked by At

The release of the 'generate' tool opens up a whole lot of exciting possibilities. I've been trying to make my tests better. I have a function which queries an external API, the location of that API is defined in a global variable. One piece of the puzzle is replacing that value with a value determined at 'generate time'.

I have:

//go:generate gofmt -w -r "var apiUrl = a -> var apiUrl = \"http://example.com\"" $GOFILE

Running go generate then errors out with:

parsing pattern var apiUrl = a  at 1:1: expected operand, found 'var'

It's not an option to use a place holder like so:

gofmt -r 'API_GOES_HERE -> "http://example.com"' -w

That's because, when I compile production code, the source gets rewritten, so subsequent compiles for testing no longer can replace the place holder (it has been replaced already).

I realise I'm abusing gofmt somewhat but I'd rather not go back to sed. What would be the valid go:generate statement?

2

There are 2 answers

0
Ainar-G On BEST ANSWER

You can use a linker flag -X for that. For example,

go build -ldflags "-X main.APIURL 'http://example.com'"

will build your program with APIURL variable set to http://example.com.

More info in the linker docs.


Go 1.5 edit: starting with Go 1.5, it's recommended to use the new format:

go build -ldflags "-X main.APIURL=http://example.com"

(Note the equals sign.)

0
Emil Davtyan On

In your test file say api_test.go add a generate command that produces another file called api_endpoint_test.go that is in the same package and only defines or inits ( using an init function ) the variable you need. That variable value will only be used during testing.


For the record, I don't quite know understand why you are trying to do it this way, instead of either initiatializing the variable during runtime or using some conventional configuration method.