As of Go 1.14, modules are ready for production. Compared to GOPATH, they make it much easier to keep workspaces clean by managing dependencies out of sight, and by letting you clone projects anywhere. However, there is no good way to simply install a Go binary from source, yet.
The core reason for this is that go get
is a software development tool, not a software distribution tool, and binaries should be distributed through package managers. However, many tools are not packaged.
Back in the GOPATH days I had a script, brew-go-get
, which would run go get
in a temporary GOPATH and then use Homebrew to safely link the binary in place, so that you could track the installation with brew list
and remove it with brew uninstall
.
I have updated the script for modules, and it works a lot better!
$ brew install FiloSottile/gomod/brew-gomod
$ brew gomod github.com/maruel/panicparse/cmd/pp
go: creating new go.mod: module gomod-pp/2020-03-15
go: downloading github.com/maruel/panicparse v1.3.0
go: found github.com/maruel/panicparse/cmd/pp in github.com/maruel/panicparse v1.3.0
go: downloading github.com/mattn/go-isatty v0.0.7
go: downloading github.com/mattn/go-colorable v0.1.1
go: downloading github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b
go: downloading golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223
Linking /usr/local/Cellar/gomod-pp/2020-03-15... 1 symlinks created
$ pp -help
Usage of pp: [...]
$ brew uninstall gomod-pp
Uninstalling /usr/local/Cellar/gomod-pp/2020-03-15... (3 files, 4.8MB)
Here's how it works:
- it creates a new Go module at
/usr/local/Cellar/gomod-$name/$date/libexec/mod
(the Cellar is where Homebrew software is installed, andlibexec
is a magic path that doesn't get linked into/usr/local
) - within that module, it runs
go get
with aGOBIN
set to/usr/local/Cellar/gomod-$name/$date/bin
- it runs
brew link gomod-$name
to get the binary linked into/usr/local/bin
Like any Homebrew installation, it's easy to track and uninstall, and manual installations like this are officially supported. The modules solution also has a number of advantages over the GOPATH solution:
- it's secured by the Go checksum database agains tampering
- it uses the system module and build cache, avoiding duplicate downloads and source trees
- it leaves behind the exact versions used in
libexec/mod/go.mod
- the built binaries have access to their own version via
debug.BuildInfo
Install the command easily with
$ brew install FiloSottile/gomod/brew-gomod
and let me know on Twitter how it works.
I've made a simple brew command to cleanly install binaries from Go modules as Homebrew packages.
— Filippo Valsorda (@FiloSottile) March 15, 2020
$ brew install FiloSottile/gomod/brew-gomod
$ brew gomod https://t.co/TzTye7BzyJ
Secured by the Go Checksum Database!https://t.co/a4LuTECcbw