去模块安装去工具

go modules installing go tools

我正在使用 go modules 作为依赖管理,我在安装这样的东西时遇到了问题:

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

上面的结果是:

go: cannot find main module; see 'go help modules'

试试这个命令 GO111MODULE=on go get -u github.com/go-critic/go-critic/...

编辑: 这里的原始答案专门提到了 Go 1.11 中工具的状态。自 Go 1.12 发布以来,这不再准确。请参阅 及其链接,了解在 Go 1.12 及更高版本中处理这种情况的详细信息。

如果 GO111MODULE var 设置为 on,你必须在初始化的 go 模块目录树中才能使用 go get,即使你试图获取 工具 而不是新的 依赖项 。这是一个已知且备受争议的问题:

https://github.com/golang/go/issues/27643

https://github.com/golang/go/issues/24250

https://github.com/golang/go/issues/25922

短期的解决方案是 运行 GO111MODULE=off go get <tool>。这明确地禁用了模块支持,即使你当前在模块包中,并强制它只使用你的 GOPATH。

从长远来看,找出通过 go get(或其他命令,如带有标志的 go install)支持工具安装的最佳解决方案是一个正在进行的讨论领域 到目前为止,几乎没有达成共识。然而,Go 1.12 有一个 PR open,如果被接受,将允许 go get 在模块外部简单地工作,即使设置了 GO111MODULE=on

对于 Go 1.12(2019 年 2 月),GO111MODULE=on go get 将有效。
(来自 issue 24250

模块

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).

刚刚在 go1.11.2 上遇到了同样的问题。尝试设置 GO111MODULE=on,但这无法解决问题。

我的解决方案:

  1. 升级到使用 go 1.12.5:https://golang.org/doc/install?download=go1.12.5.linux-amd64.tar.gz

    这可以解决 go: cannot find main module; see 'go help modules' 问题。

  2. 然后我又遇到了一个问题go: cannot use path@version syntax in GOPATH mode,

    设置env可以解决GO111MODULE=on

此时这里的其他几个答案已经过时了。

至少有两种情况需要考虑:

案例一

您想安装一个工具,但不想修改当前的 go.mod 以将该工具作为依赖项进行跟踪。

简而言之,对于 Go 1.12 或 1.13,最简单的解决方案是 cd 到一个没有 go.mod 的目录,例如:

$ cd /tmp
$ go get github.com/some/tool@v1.0.1

另外,gobin 是一个用于安装或 运行 二进制文件的模块感知命​​令,它提供了额外的灵活性,包括无需更改当前模块的 go.mod[=26 即可安装的能力=]

查看此相关 了解更多详细信息,包括 Go 1.11 的解决方案,以及 Go 1.14 中可能的新选项,用于在不更新您的 go.mod 的情况下获取工具。

案例二

另一方面,如果您想在 go.mod 中明确跟踪工具作为版本依赖项,请参阅模块 wiki 上的 "How can I track tool dependencies for a module?" 常见问题解答。

简而言之,你在单独的包中创建一个tools.go文件,并设置一个// +build tools构建标签,如:

// +build tools

package tools

import (
    _ "golang.org/x/tools/cmd/stringer"
)

import 语句允许 go 命令在模块的 go.mod 中精确记录工具的版本信息,而 // +build tools 构建约束会阻止正常构建实际导入你的工具。

我遇到了同样的问题,直接“差不多”解决了。起初它没有用。这是因为 module 已经初始化,并且在设置 GO111MODULE=on 之前我有 运行“go get...”命令。

为了让它工作,我删除了“go.mod”通过运行ning“go mod init ...”重新初始化mod并重新运行 必要的“go get ....”命令。

我遇到了同样的问题并通过以下命令解决了它。

$ go env -w GO111MODULE=auto