Generating Code with Go Generate

Generating Code with Go Generate

May 15, 2025

image

Go tends to have boilerplate code more frequently than other languages. For example, in Java, tools like Lombok can be used to create common Getters/Setters, and tools like Mockito can be utilized for mocking.

Both libraries generate code using Java Annotation Processors, but developers do not write the code directly.

In contrast, Go does not have an Annotation Processor like Java. Typically, to generate code, you must manually install a CLI and generate code through it. In my case, I use the swaggo library to work with Swagger, which parses internal code to generate the Swagger documentation file docs.json.

Additionally, various CLI tools can be used to generate code, such as using protoc for GRPC or using mockery for generating mock interfaces.

Generating Code Using Makefile

In my case, the command to generate using swag is as follows:

swag init -g ./cmd/main.go -o ./docs

Due to insufficient memory and finger fatigue from typing the same command repeatedly, it’s common to use an alias or tools like Makefile.

Here is how to generate code using a Makefile:

.PHONY: swag
swag:
    @swag init -g ./cmd/main.go -o ./docs

This allows you to generate code by running the command make swag.

Generating Code Using Go Generate

Realizing the limitations of this approach, Go provides a tool called go generate for generating code.

Go Generate allows you to write commands as comments in Go source files and execute them to generate code.

For example, when using swag, you could write as follows:

somefile.go
//go:generate swag init -g ./cmd/main.go -o ./docs

Writing it this way allows you to generate code using the command go generate ./somefile.go.

If you do not want to specify files directly, you can structure the command to traverse all Go files in the project and execute any //go:generate commands:

go generate ./...

This method is most commonly used in practical application.

Points to Note

When running Go Generate, it executes from the path of the file, so many CLI tools that use relative paths must be cautiously handled when using Go Generate.

For example, consider a structure where there is a go:generate in foo/bar.go:

foo/bar.go
//go:generate swag init -g ./cmd/main.go -o ./docs
    • bar.go
    • main.go
  • In this case, running the command go generate ./... will lead to an error as it cannot find the path ./cmd/main.go. Additionally, the output path ./docs is also written as a relative path, thus it would be generated under foo/docs.

    Therefore, when using relative paths, caution must be taken with Go Generate.

    //go:generate swag init -g ../cmd/main.go -o ../docs

    References