当顶级模块及其子模块之一作为单独的版本分别导入时,如何解决冲突的 go 模块依赖关系?

How to resolve conflicting go module dependencies when a top-level module and one of its sub-modules are separately imported as separate versions?

我的项目中有两个依赖项。

go.mod:

module github.com/test-org/test-repo

go 1.12

require (
    github.com/foo/bar v1.0.0
    github.com/raz/mataz v1.0.0
)

在 运行ning go mod download 之后,这两个依赖关系导致要下载 github.com/shared/dependency 的两个不同版本。有趣的是 github.com/shared/dependency 包含子模块,例如:

dependency
  -- go.mod
  -- api
      -- go.mod

检查下载的模块显示有两个版本已下载到我的本地计算机:

ls ${GOPATH}/pkg/mod/github.com/shared:

[dir] dependency    [dir] dependency@v1.1.0

ls ${GOPATH}/pkg/mod/github.com/shared/dependency:

[dir] api@v1.2.0

查看这些目录的内容:

${GOPATH}/pkg/mod/github.com/shared/dependency@v1.1.0:

v1.1.0 中整个 repo 的文件内容,包括 api 文件夹及其自己的 go.mod 文件。

${GOPATH}/pkg/mod/github.com/shared/dependency/api@v1.2.0:

v1.2.0版本库api文件夹的文件内容,包括go.mod文件。


最后,我的 test-repo 中有一个 .go 文件,其设置如下:

package test-package

import (
    "github.com/foo/bar"
)

func MyFunc() {...bar.NewBar()...}

当我尝试 运行 测试 MyFunc(存在于其他地方)时,我收到一条 unknown import path...ambiguous import... 错误消息。例如

go test github.com/test-org/test-repo/test-package -test.run=TestMyFunc -v:

unknown import path "github.com/shared/dependency/api": ambiguous import: found github.com/shared/dependency/api in multiple modules:
    github.com/shared/dependency v1.1.0 (${GOPATH}/pkg/mod/github.com/shared/dependency@v1.1.0/api)
    github.com/shared/dependency v1.2.0 (${GOPATH}/pkg/mod/github.com/shared/dependency/api@v1.2.0)

错误指向 github.com/foo/bar 库中导入 github.com/shared/dependency/api.go 文件的 import 行。鉴于有两个可用版本,它不知道在我的本地 ${GOPATH}/pkg/mod 文件夹中选择哪个 api

  1. ${GOPATH}/pkg/mod/github.com/shared/dependency@v1.1.0/api
  2. ${GOPATH}/pkg/mod/github.com/shared/dependency/api@v1.2.0

有什么方法可以让 go test 调用正常工作(解决依赖冲突)?我的两个依赖项都没有明确要求下载完整的 shared/dependency@v1.1.0,但由于某种原因它被拉了进来。如果没有,它似乎可以解决问题。

问题原来是其中一个依赖项引用了 github.com/shared/dependency/api 的一个版本,即 pre-go-modules

这导致 go 工具具有对 github.com/shared/dependency/api 子模块的模块引用,而且还为 pre-go-modules 版本的整个 github.com/shared/dependency repo 的黑盒导入。在这个例子中,这意味着 v1.2.0 有 go 模块(有一个 go.mod 文件),而 v1.1.0 没有。

将以下行添加到我的 go.mod 文件中能够解决问题,并且此解决方案适用于我遇到此类冲突的多个依赖项:

replace (
    github.com/shared/dependency => github.com/shared/dependency v1.2.0
)

请注意,此解决方案仅适用于我们强制引用共享依赖项以使用支持 go-module 的版本 (v1.2.0+)。