I\'ve recently started with Go 1.11 and love the modules. Apart from runtime dependencies I need to work with go modules during the build, e.g. during go generate
tools.go
is a great solution if you're building an app or service. But if you're building a library, tools.go
still leaks dependencies to things consuming your library (your tools are still there as indirect
dependencies, and go mod tidy
will pull them in since it considers every possible target). That's not the end of the world since those modules never end up in the actual built binaries of the consumer, but it's still messy.
https://github.com/myitcv/gobin/issues/44 is probably the most promising approach to fixing this long term, but short term I've used a combination of the "internal module" approach explained there along with https://github.com/izumin5210/gex.
First, I install gex
globally:
GO111MODULE=off go get github.com/izumin5210/gex/cmd/gex
Then before actually using gex I create a structure like this:
myproject/
\
- go.mod: module github.com/ysamlan/myproject
\
internal/
\
tools/
- go.mod: module github.com/ysamlan/myproject/tools
To install a build-only tool I just cd internal/tools
and run gex --add (sometool)
, which puts that tool in internal/tools/bin
. CI scripts and other folks that want to build my stuff locally just need to run cd internal/tools && gex --build
to reliably and reproducibly populate the tool binaries, but the top-level go.mod is unchanged.
The key piece there is creating that internal/tools/go.mod
file with a different module path than the one the root project uses, and then only running gex
from that directory.