go modules installing go tools
Edit: The original answer herein referred specifically to the state of the tooling in Go 1.11. Since the release of Go 1.12, this is no longer accurate. Please see this answer, and the ones it links to, for details of handling this situation in Go 1.12 and later.
If the GO111MODULE
var is set to on
, you have to be inside an initialized go module directory tree in order to use go get
, even if you're trying to get a tool rather than a new dependency. This is a known and heavily debated issue:
https://github.com/golang/go/issues/27643
https://github.com/golang/go/issues/24250
https://github.com/golang/go/issues/25922
The solution, short term, is to run GO111MODULE=off go get <tool>
. This explicitly disables the module support, even if you're in a module package currently, and forces it to only utilize your GOPATH.
Long-term, figuring out what the best solution is to support tool install via go get
(or another command, like go install
with a flag) is an ongoing area of discussion with
little in the way of established consensus as of yet. However, there's a PR open for Go 1.12 that, if accepted, will allow go get
to simply work while outside a module, even with GO111MODULE=on
set.
Several of the other answers here have grown stale at this point.
There are at least two cases to consider:
Case 1
You want to install a tool, but you don't want to modify your current go.mod
to track that tool as a dependency.
In short, with Go 1.12 or 1.13, the simplest solution is to cd
to a directory without a go.mod
, such as:
$ cd /tmp
$ go get github.com/some/[email protected]
Alternatively, gobin is a module-aware command to install or run binaries that provides additional flexibility, including the ability to install without altering your current module's go.mod
See this related answer for more details, including a solution for Go 1.11, as well as the likely new option in Go 1.14 for getting a tool without it updating your go.mod
.
Case 2
On the other hand, if you want to explicitly track a tool as a versioned dependency in your go.mod
, then see the "How can I track tool dependencies for a module?" FAQ on the modules wiki.
In short, you create a tools.go
file in a separate package, and set a // +build tools
build tag, such as:
// +build tools
package tools
import (
_ "golang.org/x/tools/cmd/stringer"
)
The import statements allow the go
command to precisely record the version information for your tools in your module's go.mod
, while the // +build tools
build constraint prevents your normal builds from actually importing your tools.