Since Golang version 1.11 this process is finally (almost) as easy as it should (!!). You can see full docs here. For older guides see here.
These are my notes, not a generic solution. They are not meant to work anywhere outside my machines. Update version numbers to whatever are the current ones while you do this.
asdf
lives in https://github.com/asdf-vm/asdf
Follow its installation instructions, which at the moment of writing were:
cd
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.6.0
# For Ubuntu or other linux distros
echo '. $HOME/.asdf/asdf.sh' >> ~/.bashrc
echo '. $HOME/.asdf/completions/asdf.bash' >> ~/.bashrc
On a new terminal, install Golang plugin:
asdf plugin-add golang
Then install Golang:
asdf install golang 1.11
Set some Golang version as global if you don't have none:
asdf global golang 1.11
If you happen to be using SSH to authenticate with github (I recommend that), then you may want to add this to your .gitconfig
:
[url "[email protected]:"]
insteadOf = https://github.com/
This will prevent go get
from using https
login when accessing github.
You should at least read the basics from here.
You just go into your git root folder, fix your Golang version asdf local golang 1.11
, and run go mod init public/route/of/your/repo
. That will scan all your source files for dependencies, and create a go.mod
and a go.sum
file. These should go into version control. From now on, any go command you run from within this folder will take those files as reference to lookup their dependencies.
Provided the project was created following this guide, it is straightforward to start working on it. You should clone it, then cd
into its folder, run asdf install
to get the right Golang version, and build the project, or run its tests. Go will download and build all code depedencies.
For tooling dependencies there should be a setup.sh
script that takes care of running go get
for each tool. The actual version installed will be the one in the go.mod
file. See Toooling.
Simply import the new dependency from a source file, and build your project. Go will catch up with it and update go.mod
and go.sum
files. If the new dependency was not a Go module already, then it may have some indirect dependencies that also need to be tracked. Just run go mod tidy
to track them.
Just remove any reference from it on your code, and run go mod tidy
. Go will catch up with it and update go.mod
and go.sum
files.
Tooling is still out of control, as it is not imported (and it should not!) from your code. Thus a simple go build
will not install them, even if they are mentioned somewhere inside go.mod
. You still have to go get
. We'll see how it evolves through go1.12. There are some tricks out there that try to help with this though.
The current recommended way to do this (see here) is simply by writing a regular Go code file that imports your tools, thus enabling Go itself to keep track of them as any other dependency. The final trick is to add the build constraint to avoid being included into regular builds. Some tools.go
file like this would do:
// +build tools
package tools
import (
_ "github.com/my/development/tool"
)
Then run go get github.com/my/development/tool
to get it installed and mapped to go.mod
. go mod tidy
would also map it to go.mod
if the tool was already installed. When you run go get github.com/my/development/tool
again after you clone this project somewhere else, it will pick up the version fixed in go.mod
.
Therefore it is a good practice to have a setup.sh
script that runs go get
for every tool. That way fellow programmers can reproduce the development environment.
This approach does not solve the problem, as this will share the same binary for the tool among different projects that use the same version of Go (TODO: make sure of this).
After installing any golang binary you need to run asdf reshim golang
. That will make any binary present in your current Go version to be available from your PATH. That would be the case for a newly installed Go tool, for example.