For a long time, Golang provides an extremely simple dependency management model. It just depends on Git repos and actually its master
branch.
If you have experience on concepts and tools like monorepo/Gerrit, you can easily get the point why it was initially designed like this1 including the existence of GOPATH
. That is because Google uses monorepo.
There are some advantages claimed2 and Golang’s dependency management could work on that well.
However, monorepo does not dominate the world. The dominance of open source community is GitHub. In contrast, GitHub follows fork & pull request workflow.
This (Go’s dependency management design) leads to lots of issues:
master
makes breaking change, it breaks build.To make it easier, there are some efforts:
By these tools, we may handle vendors better. But these tools are not officialy supported and it needs commit all vendor packages to repository! Can you imagine a frontend or Node.js project commits its node_modules
? This is ridiculous.
I don’t know the decision process, but Golang team finally launched Go Module in 1.11, which embraces the non-monorepo part of the world.
GOPATH
, and now we can clone to anywhere.go get
inside a repo is not global, it works only at local.vendor
go.mod
with git tags, commit hashes, and semver.Enable Go Module, edit .bashrc
or .zshrc
:
export GO111MODULE=on
Initialize Go Module
go mod init .
go mod tidy
go get github.com/crispgm/go-g
go get -u github.com/crispgm/go-g
go get -u
go get github.com/crispgm/go-g@master
go get github.com/crispgm/go-g@1.0.0
go get github.com/crispgm/go-g@617f32e
go mod vendor
I highly not recommend this, since getting rid of vendor is one of the major advantages of Go Module.
There is a Go modules support guide in vscode-go plugin. It is actually very easy that we just need to enable Language Server for go by adding one line to settings.json
:
"go.useLanguageServer": true
One of our in-house library depends on satori/go.uuid, with traditional go get
it means depend on master
. But Go Module got the latest tag by default. So the solution should be:
go get -u github.com/satori/go.uuid@master
It is actually caused by gin-gonic/gin (the web framework we use) and there is a solution:
Add the following to go.mod
to solve the trouble.
replace github.com/ugorji/go v1.1.4 => github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43
Go Module is not a silver bullet, and it is more a compatibility than a fix. But for me, it is great improvement.