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

     2023-03-07     229

关键词:

【中文标题】当***模块及其子模块之一作为单独版本单独导入时,如何解决冲突的 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? 【发布时间】:2020-01-17 00:40:33 【问题描述】:

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

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
)

运行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中repo的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)

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

    $GOPATH/pkg/mod/github.com/shared/dependency@v1.1.0/api $GOPATH/pkg/mod/github.com/shared/dependency/api@v1.2.0

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

【问题讨论】:

主版本 > 1 的包必须以“/v2”结尾的导入路径导入。您不能在两个不同版本中拥有相同的包(由其导入路径标识)。这就是为什么不同的版本需要不同的导入路径:Append v2.查阅解释所有这些的 Go Modules wiki。 (可能重复)。 Go 模块概念建立在模块必须根据 semver 进行语义版本控制。如果你的一个要求是v1.12,另一个是v1.0,那是相同的主要版本,因此v1.12必须与v1.0兼容,所以go工具会选择v1.12应该可以工作.如果您需要不同的主要版本,以v2 开头的它必须是导入路径的一部分,因此它将被视为不同的包/依赖项,并且所有不同的主要版本都将单独包含。 @Volker,我已经更改了问题中的版本,因为我的问题实际上不是v1v2,而是v0v1。所以你的建议不适用。不过,我不知道您提到的v2+ 细节。很高兴知道。 不能拥有同一个包的 v0.0.0 和 v1.0.0。死的简单。 v0.0.0 甚至无效,仅用于兼容性。有时你所能做的就是修复上游。 @Volker 好的,所以如果我的一个依赖项需要 v0.x.x 版本的包,而另一个依赖项需要 v1.x.x 版本,唯一的解决方案是更改以下要求之一这些依赖项在其go.mod 文件中吗?那是对的吗?最初使用 go modules 时,我的印象是子模块可能能够摆脱不同的版本。例如,如果我在我的 repo 中为需要其他版本的依赖项的包创建了第二个 go.mod 文件,我认为这可能有效,但我可能会偏离 go 模块的能力。跨度> 【参考方案1】:

问题是其中一个依赖项引用了 pre-go-modulesgithub.com/shared/dependency/api 版本。

这导致 go 工具有一个对 github.com/shared/dependency/api 子模块的模块引用,而且还对 pre-go-modules 版本的整个 github.com/shared/dependency 存储库进行了黑盒导入。在这个例子中,这意味着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+)。

【讨论】:

模块使用面向对象介绍

模块使用模块是Python组织代码的基本方式。一个Python脚本可以单独运行,也可以导入到另一个脚本中运行,当脚本被导入运行时,我们将其称为模块(module)。所有的.py文件都可以作为一个模块导入模块名与脚本的文件名相同例... 查看详情

15模块

模块简介模块是python组织代码的基本方式python的脚本都是用扩展名为py的文本文件保存的,一个脚本可以单独运行,也可以导入另一个脚本中运行。当脚本被导入运行时,我们将其称为模块(module)包python的模块可以按目录组织为... 查看详情

导入模块时发生的奇怪事情

】导入模块时发生的奇怪事情【英文标题】:Weirdstuffhappeningwhileimportingmodules【发布时间】:2011-11-2521:16:52【问题描述】:我不想在这个标题下提出问题,但实际上我不知道发生了什么,所以就这样吧。我正在做另一个项目,我... 查看详情

使用 Jasmine 单独测试 Marionette 模块

】使用Jasmine单独测试Marionette模块【英文标题】:TestingMarionetteModulesinisolationwithJasmine【发布时间】:2013-03-2506:35:47【问题描述】:我有一个Marionette项目,类似于http://www.backbonerails.com/中描述的设置我正在使用Rails、Coffeescript和Jasm... 查看详情

当实现在单独的模块单元中时,C ++ 20模块程序失败

】当实现在单独的模块单元中时,C++20模块程序失败【英文标题】:C++20Moduleprogramfailswhenimplementationisinseparatemoduleunit【发布时间】:2022-01-0506:07:53【问题描述】:在重构我的项目以与模块一起使用之前,我编写了一个测试项目ExIm... 查看详情

当路由在单独的模块中时,如何使用 Node+Mongo 进行连接池? [复制]

】当路由在单独的模块中时,如何使用Node+Mongo进行连接池?[复制]【英文标题】:HowtodoconnectionpoolingwithNode+Mongowhenroutesareinseparatemodule?[duplicate]【发布时间】:2016-04-2004:47:55【问题描述】:Mongo文档展示了在同一模块中定义MongoClie... 查看详情

01月09日四周二次

2.5/2.6模块使用2.7面向对象介绍2.5/2.6模块使用模块模块是python组织代码的基本方式一个python脚本可以单独运行,也可以导入到另一个脚本中运行,当脚本被导入运行时,我们将其城为模块(module)所有的.py文件都可以作为一个模块导入... 查看详情

从单独的模块导入 Emotion 样式部分会产生不正确的结果,但从文件导入有效

】从单独的模块导入Emotion样式部分会产生不正确的结果,但从文件导入有效【英文标题】:ImportinganEmotionstylepartialfromaseparatemoduleyieldsimproperresults,butimportingfromfileworks【发布时间】:2020-03-1617:13:29【问题描述】:我正在使用Webpack... 查看详情

将模块重构为单独的文件时,Vuex 4模块不起作用

】将模块重构为单独的文件时,Vuex4模块不起作用【英文标题】:Vuex4modulesnotworkingwhenrefactoringmodulestosepratefiles【发布时间】:2021-11-2810:45:39【问题描述】:我一直在学习vuex4,在那里我在main.js中编写了所有状态、动作、getter...现... 查看详情

智能设备中模块单独升级方案探索

1.概述OTA又称FOTA即固件空中升级(firmwareovertheair)是物联网设备必备功能之一,主要负责对设备的bug修复和版本更新以及资源文件升级等;随着物联网的发展,物联网设备也越来越复杂,出现了一个物联网... 查看详情

在单独的模块中,Python getpass 在第二次尝试时工作

】在单独的模块中,Pythongetpass在第二次尝试时工作【英文标题】:Pythongetpassworksatsecondattemptwheninseparatemodule【发布时间】:2021-10-3005:00:18【问题描述】:我尝试使用带有getpass()函数的单独模块,例如#!/usr/bin/python3fromgetpassimportgetp... 查看详情

模块作为Python中没有.py的脚本?

】模块作为Python中没有.py的脚本?【英文标题】:moduleasscriptwithout.pyinPython?【发布时间】:2014-02-1112:15:52【问题描述】:我想要一个Python文件,其中包含名为\'foobar\'的代码,该文件旨在在安装包时作为脚本执行:$foobar-iarg1arg2foo... 查看详情

qml——添加自定义模块

一、模块的定义在使用QML时,我们常常看到类似这样的语句:importQtQuick2.0importQtSensors5.0通过这些import语句,我们就能使用QML中的相关控件了。其实这就是导入模块的意思,它包括3个部分:import关键字、模块名称、版本号。模块... 查看详情

单独编译内核模块(代码片段)

前言在开发和调试某个内核模块时,如果采用整体编译内核的方式,那效率就太低了。我们通常采用单独编译的方式进行。step1拷贝内核模块到workspace,以英特尔以太网卡驱动drivers/net/ethernet/intel/为例cplinux-5.13/drivers/n... 查看详情

十.模块和库(代码片段)

1.模块操作:导入单独的模块:把模块文件的位置,添加到sys.path中。(不常用)把模块放到“lib\\site-packages\\”目录下。(PyCharm兼容性更好)导入包(文件夹):方法与单独模块一样,且包下面必须要有__init__.py文件#模块... 查看详情

Blender Python - 在导入所有类时强制重新加载模块

】BlenderPython-在导入所有类时强制重新加载模块【英文标题】:BlenderPython-Forcereloadofmodulewhileimportingallitsclasses【发布时间】:2021-11-2118:11:55【问题描述】:我正在使用Python/Blender进行开发,这里有两个需求:从我的模块中导入所... 查看详情

打印模块的版本而不导入整个包

】打印模块的版本而不导入整个包【英文标题】:Printversionofamodulewithoutimportingtheentirepackage【发布时间】:2018-01-1319:01:46【问题描述】:如果只导入一个模块,是否可以检查包的版本?当一个包被导入时...importpandasaspd我用:print(... 查看详情

ES6 模块:导出单个类的静态方法或多个单独的方法

】ES6模块:导出单个类的静态方法或多个单独的方法【英文标题】:ES6modules:ExportsingleclassofstaticmethodsORmultipleindividualmethods【发布时间】:2015-07-0518:42:02【问题描述】:我正在使用ECMAScript6模块。从以下选项从模块导出/导入多个... 查看详情