Go.mod 中的“不兼容”是什么意思,它会造成伤害吗?

我在我的项目中使用 Goczmq,类似于 next:

主要内容:

package main


import (
_ "github.com/zeromq/goczmq"
)


func main() {
}

而且,我使用 golang 1.12和 gomod 来管理我的项目。

接下来,我使用了 go mod init xxx,在构建时,它会自动为我下载 goczmq,并向 go.mod添加依赖项,但是其中包含 incompatible。(但对于其他库,我可能会得到类似于 github.com/kolo/xmlrpc v0.0.0-20190717152603-07c4ee3fd181的东西)

去吧,现代版:

module pigeon


go 1.12


require (
github.com/zeromq/goczmq v4.1.0+incompatible
)

从一些讨论(对于其他库) ,例如 这个,似乎库所有者应该做一些事情来支持 golang 1.12?但在我的情况下,所有的工作都很好,只是一个 incompatible有点让我担心(我的意思是现在看起来一切都很好,但有一天当我使用一个 API,我从来没有使用过,会有隐藏的炸弹...

所以我的问题是:

我应该担心这个吗,还是这就是我想要的?

34086 次浏览

+incompatible means the dependency has a semver major version of 2 or higher and is not a Go module yet (it doesn't have go.mod in its source code).

Accepted answer is correct, but really not friendly for me who just get in touch with go module. I made some investigation base on the answer & make a conclusion base on this as next, in case anyone needed:

Standard commands like go build or go test will automatically add new dependencies as needed to satisfy imports (updating go.mod and downloading the new dependencies). But there are several different situations which will result in the different version selections:

  1. If a repository has not opted in to modules but has been tagged with valid semver tags, meanwhile, it's v0/v1 module, see this:

    not opted in to modules: means no go.mod in source tree

    valid semver tags: means the repo use git tag to tagged as something like vX.Y.Z

    v0/v1 module: means the value of major version(that is X) is 0 or 1, e.g. v0.1.0, v1.2.3

    Then, it will use a pseudo-version, something like github.com/kolo/xmlrpc v0.0.0-20190717152603-07c4ee3fd181

  2. If a repository has not opted in to modules but has been tagged with valid semver tags, meanwhile, it's a v2+ module, see this:

    v2+ module: means the value of major version(that is X) is >=2,e g. v4.1.0

    Then, it will show as incompatible, something like github.com/zeromq/goczmq v4.1.0+incompatible

  3. If a repository has already opted in to modules, but not have been tagged with valid semver tags:

    Then, it will behave as 1, use pseudo-version.

  4. If a repository has already opted in to modules, and has been tagged with valid semver tags, meanwhile, it's a v0/v1 module:

    Then, it will behave normally like github.com/stretchr/testify v1.3.0

  5. If a repository has already opted in to modules, and has been tagged with valid semver tags, meanwhile, it's a v2+ module:

    Then, when import in sourcecode, we need add /vN at the end, e.g., import "github.com/my/mod/v4", and in go.mod it will behave like github.com/my/mod/v4 v4.1.0

The module name should have been github.com/zeromq/goczmq/v4 instead of github.com/zeromq/goczmq for versions v4 and above (v4.1.0, v4.2.0, etc).

Since github.com/zeromq/goczmq has not adopted Go modules correctly, the go get will fail if Go 1.13 is used and the GOPROXY is set to direct or to some other server that does not host this file -

    go get github.com/zeromq/goczmq@v4.2.0+incompatible
go: finding github.com v4.2.0+incompatible
go: finding github.com/zeromq v4.2.0+incompatible
go: finding github.com/zeromq/goczmq v4.2.0+incompatible
go: finding github.com/zeromq/goczmq v4.2.0+incompatible
go get github.com/zeromq/goczmq@v4.2.0+incompatible: github.com/zeromq/goczmq@v4.2.0+incompatible: invalid version: +incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required


More details mentioned under the 'Version validation' section here - https://golang.org/doc/go1.13#modules

Note - GoSUMDB also won't have such entries so even if you set the GOPROXY to a server that hosts this file and if GOSumDB is enabled, then you will get something like this -

    ➜  ~ export GOPROXY=https://gocenter.io
➜  ~ go get github.com/zeromq/goczmq@v4.2.0+incompatible
go: finding github.com/zeromq/goczmq v4.2.0+incompatible
go: finding github.com/zeromq v4.2.0+incompatible
go: finding github.com v4.2.0+incompatible
go: downloading github.com/zeromq/goczmq v4.2.0+incompatible
verifying github.com/zeromq/goczmq@v4.2.0+incompatible: github.com/zeromq/goczmq@v4.2.0+incompatible: reading https://gocenter.io/sumdb/sum.golang.org/lookup/github.com/zeromq/goczmq@v4.2.0+incompatible: 404 Not Found


The correct solution will be to follow up with the module author to make sure that they are adopting Go modules correctly by adding a suffix to the module name.

There is a workaround but have to check if it's working by design i.e. point GOPROXY to a server that hosts this file and then use GOPRIVATE to exclude this specific module version from GoSumDB validation -


root@715c3b39bb12:/go# export GOPROXY=https://gocenter.io
root@715c3b39bb12:/go# unset GOPRIVATE


root@715c3b39bb12:/go# go get github.com/zeromq/goczmq@v4.2.0+incompatible
go: finding github.com v4.2.0+incompatible
go: finding github.com/zeromq/goczmq v4.2.0+incompatible
go: finding github.com/zeromq v4.2.0+incompatible
go: downloading github.com/zeromq/goczmq v4.2.0+incompatible
verifying github.com/zeromq/goczmq@v4.2.0+incompatible: github.com/zeromq/goczmq@v4.2.0+incompatible: reading https://gocenter.io/sumdb/sum.golang.org/lookup/github.com/zeromq/goczmq@v4.2.0+incompatible: 404 Not Found


root@715c3b39bb12:/go# export GOPRIVATE=github.com/zeromq/goczmq


root@715c3b39bb12:/go# go get github.com/zeromq/goczmq@v4.2.0+incompatible


go: downloading github.com/zeromq/goczmq v4.2.0+incompatible
go: extracting github.com/zeromq/goczmq v4.2.0+incompatible
# pkg-config --cflags  -- libczmq libzmq libsodium
Package libczmq was not found in the pkg-config search path.
Perhaps you should add the directory containing `libczmq.pc'


However, will still recommend reaching out to the module author to fix the module name in their go.mod file.