By Daniel Martí, Go contributor, maintainer of encoding/json
,
and tool author.
Users need a simple, easy-to-remember way to install Go programs. Similarly, tool authors need a short one-liner they
can include at the top of their README.md
explaining how to install the tool.
Go 1.16 introduces a new way to install Go programs directly with the go
command. This guide
introduces the new mode of go install
using the example of
filippo.io/mkcert
, and is suitable for both end users and tool authors.
Prerequisites
You should already have completed:
This guide is running with:
$ go version
go version go1.16 linux/amd64
Background
Currently, tool authors who want to provide installation instructions in their projects’ README.md
typically include:
$ go get filippo.io/mkcert@v1.4.2
go: downloading filippo.io/mkcert v1.4.2
go: downloading golang.org/x/net v0.0.0-20190620200207-3b0461eec859
go: downloading golang.org/x/tools v0.0.0-20191108193012-7d206e10da11
go: downloading honnef.co/go/tools v0.0.0-20191107024926-a9480a3ec3bc
go: downloading howett.net/plist v0.0.0-20181124034731-591f970eefbb
go: downloading software.sslmate.com/src/go-pkcs12 v0.0.0-20180114231543-2291e8f0f237
go: downloading golang.org/x/text v0.3.0
go: downloading github.com/BurntSushi/toml v0.3.1
Note: most README.md
instructions that use go get
do not specify a version. This results in the latest
version of a package being fetched. A specific version, v1.4.2
, is used here to ensure this guide
remains reproducible.
There are a number of problems with this approach:
- A user might run the above
go get
within a module, which would update the current module’s dependencies, rather than just installing the tool directly. go get
might not be running in module mode at all, for example if the user previously modifiedGO111MODULE
.- The use of
go get
is confusing; it is used to download and install executables, but it’s also responsible for managing dependencies ingo.mod
files.
Prior to Go 1.16, the general advice to fix the first two problems was to use a snippet
which runs go get
in module mode and outside any module, by using a temporary directory:
$ (cd $(mktemp -d); GO111MODULE=on go get filippo.io/mkcert@v1.4.2)
However, this new approach had its own problems:
- It’s not user-friendly; the extra shell is confusing to newcomers, and hard to remember.
- It’s not cross platform; the command is not guaranteed to work on Windows.
It is clear that neither method is satisfactory, especially for README.md
instructions which are meant to be brief and easy to follow.
go install
in Go 1.16
In Go 1.16, the go install
command is now used to install programs directly, i.e. regardless of the current
module context:
$ go install filippo.io/mkcert@v1.4.2
For the purposes of this guide you are using a specific version (v1.4.2
). Alternatively,
the special latest
version can be used to install the latest release.
Much like the previous behaviour of go get
, go install
places binaries in $GOPATH/bin
,
or in $GOBIN
if set. See the “Setting up your PATH
“ section in Installing Go to ensure
your PATH
is set correctly.
Verify that mkcert
is now on your PATH
:
$ which mkcert
/home/gopher/go/bin/mkcert
Run mkcert
to check everything is working:
$ mkcert -version
v1.4.2
You can also use go version
to see the module dependencies used in building the program:
$ go version -m $(which mkcert)
/home/gopher/go/bin/mkcert: go1.16
path filippo.io/mkcert
mod filippo.io/mkcert v1.4.2 h1:7mWofpFS4gzQS5bhE3KYBwzfceIPy2KJ4tMT31aPNeY=
dep golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
dep golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
dep software.sslmate.com/src/go-pkcs12 v0.0.0-20180114231543-2291e8f0f237 h1:iAEkCBPbRaflBgZ7o9gjVUuWuvWeV4sytFWg9o+Pj2k=
To eliminate redundancy and confusion, using go get
to build or
install programs is being deprecated in Go 1.16.
Conclusion
That’s it! Time to sit back and wait for the release of Go 1.16!
As a next step you might like to consider: