go modules installing go tools
Asked Answered
W

7

29

I'm using go modules as dependency management, and I'm having problem to install something like this:

go get -u github.com/go-critic/go-critic/...

the result from above was:

go: cannot find main module; see 'go help modules'
Winburn answered 19/11, 2018 at 4:9 Comment(4)
Did you init main module "go mod init <module name>"? For better understanding go to this stackoverflow question. #52329452Bilinear
sorry for the bad description, my problem is to install cli tools into my $GOPATH/bin directory.Winburn
See this related answer, which covers options for Go 1.11, the related functionality added in Go 1.12, and what hopefully will be supported in Go 1.14.Rattail
go install golang.org/x/tools/...@latestBaksheesh
V
17

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.

Vescuso answered 20/11, 2018 at 22:12 Comment(2)
github.com/golang/go/wiki/… => GO111MODULE=on or GO111MODULE=autoDispense
FWIW, this answer was correct, but is no longer correct. See this answer for more details and the answer as of Go 1.12, 1.13, and the likely new option in Go 1.14 for getting a tool without it updating your go.mod. Also, that answer covers what to do if you want to explicitly track a tool as a versioned dependency in your go.mod (e.g., maybe because you want everyone to use the exact same version of a linter or code generator to avoid flapping due to slightly different versions of a tool in use by different people).Rattail
R
19

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 //go:build tools build tag, such as:

//go:build tools
// +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.

Rattail answered 1/8, 2019 at 22:44 Comment(3)
I've just spent the day trying to untangle all the problems caused by the tools.go hack. I would suggest that people do not use it. See github.com/golang/go/issues/33926Uttica
For case 2, if I run go mod download on a freshly cloned project that has a tools.go file, do I then have to manually run go install <tool> for each tool listed in the tools.go file or is there a single go command that installs all tools?Troopship
@SamHerrmann, yes, you then manually run go install <tool> A walkthrough in (Go By Example repo)[github.com/go-modules-by-example/index/blob/master/010_tools/… is a helpful example In the example of stringer, after setting of the tools.go file as shown above, you would run > $ go install golang.org/x/tools/cmd/stringerStereoscopic
V
17

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.

Vescuso answered 20/11, 2018 at 22:12 Comment(2)
github.com/golang/go/wiki/… => GO111MODULE=on or GO111MODULE=autoDispense
FWIW, this answer was correct, but is no longer correct. See this answer for more details and the answer as of Go 1.12, 1.13, and the likely new option in Go 1.14 for getting a tool without it updating your go.mod. Also, that answer covers what to do if you want to explicitly track a tool as a versioned dependency in your go.mod (e.g., maybe because you want everyone to use the exact same version of a linter or code generator to avoid flapping due to slightly different versions of a tool in use by different people).Rattail
I
8

I faced the same issue and resolved it by the below command.

$ go env -w GO111MODULE=auto

Introrse answered 3/3, 2021 at 4:57 Comment(0)
S
5

With Go 1.12 (February 2019), GO111MODULE=on go get will work.
(From issue 24250)

Modules

When GO111MODULE is set to on, the go command now supports module-aware operations outside of a module directory, provided that those operations do not need to resolve import paths relative to the current directory or explicitly edit the go.mod file.
Commands such as go get, go list, and go mod download behave as if in a module with initially-empty requirements.
In this mode, go env GOMOD reports the system's null device (/dev/null or NUL).

Selfimmolating answered 13/1, 2019 at 21:40 Comment(0)
E
0

Try this command GO111MODULE=on go get -u github.com/go-critic/go-critic/...

Ectophyte answered 19/11, 2018 at 4:11 Comment(1)
the magic doesnt work. i already export GO111MODULE=on. what i want is to install cli tools into my $GOPATH/bin directory with GO111MODULE=on. it made the go get tool behave different after turn on the GO111MODULE.Winburn
W
0

Just had the same issue on go1.11.2. Tried to set GO111MODULE=on, but this couldn't fix it.

My solution:

  1. Upgrade to use go 1.12.5: https://golang.org/doc/install?download=go1.12.5.linux-amd64.tar.gz

    This can resolve go: cannot find main module; see 'go help modules' issue.

  2. Then I got another issue go: cannot use path@version syntax in GOPATH mode,

    which can be resolved setting env GO111MODULE=on

Wiper answered 28/5, 2019 at 6:18 Comment(0)
M
0

I had the same problem and it was "almost" solved directly. At first it did not work. This was because the module was already initialized and I had run the "go get..." command before I had set GO111MODULE=on.

To get it working I removed "go.mod" reinitialized the mod by running "go mod init ..." and re run the necessary "go get ...." commands.

Metallurgy answered 31/10, 2020 at 15:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.