Go依赖包管理--间接依赖
1.indirect含义
在使用 Go module 过程中,随着引入的依赖增多,也许你会发现go.mod文件中部分依赖包后面会出现一个// indirect的标识。这个标识总是出现在require指令中,其中//与代码的行注释一样表示注释的开始,indirect表示间接的依赖。
比如开源软件 Kubernetes(v1.17.0版本)的 go.mod 文件中就有数十个依赖包被标记为indirect:
require (
github.com/Rican7/retry v0.1.0 // indirect
github.com/auth0/go-jwt-middleware v0.0.0-20170425171159-5493cabe49f7 // indirect
github.com/boltdb/bolt v1.3.1 // indirect
github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b // indirect
github.com/codegangsta/negroni v1.0.0 // indirect
...
)
在执行命令go mod tidy时,Go module 会自动整理go.mod 文件,如果有必要会在部分依赖包的后面增加// indirect注释。一般而言,被添加注释的包肯定是间接依赖的包,而没有添加// indirect注释的包则是直接依赖的包,即明确的出现在某个import语句中。
然而,这里需要着重强调的是:并不是所有的间接依赖都会出现在 go.mod文件中。
间接依赖出现在go.mod文件的情况,可能符合下面所列场景的一种或多种:
- 直接依赖未启用 Go module
- 直接依赖go.mod 文件中缺失部分依赖
1.2 直接依赖未启用 Go module
如下图所示,Module A 依赖 B,但是 B 还未切换成 Module,也即没有go.mod文件,此时,当使用go mod tidy命令更新A的go.mod文件时,B的两个依赖B1和B2将会被添加到A的go.mod文件中(前提是A之前没有依赖B1和B2),并且B1 和B2还会被添加// indirect的注释。

此时Module A的go.mod文件中require部分将会变成:
require (
B vx.x.x
B1 vx.x.x // indirect
B2 vx.x.x // indirect
)
依赖B及B的依赖B1和B2都会出现在go.mod文件中。
1.2 直接依赖 go.mod 文件不完整
如果依赖B没有go.mod文件,则Module A 将会把B的所有依赖记录到A 的go.mod文件中。即便B拥有go.mod,如果go.mod文件不完整的话,Module A依然会记录部分B的依赖到go.mod文件中。
如下图所示,Module B虽然提供了go.mod文件中,但go.mod文件中只添加了依赖B1,那么此时A在引用B时,则会在A的go.mod文件中添加B2作为间接依赖,B1则不会出现在A的go.mod文件中。

此时Module A的go.mod文件中require部分将会变成:
require (
B vx.x.x
B2 vx.x.x // indirect
)
由于B1已经包含进B的go.mod文件中,A的go.mod文件则不必再记录,只会记录缺失的B2。
2.总结
为什么要记录间接依赖?
如果某个依赖B 没有go.mod文件,在A 的go.mod文件中已经记录了依赖B及其版本号,为什么还要增加间接依赖呢?
我们知道Go module需要精确地记录软件的依赖情况,虽然此处记录了依赖B的版本号,但B的依赖情况没有记录下来,所以如果B的go.mod文件缺失了(或没有)这个信息,则需要在A的go.mod文件中记录下来。此时间接依赖的版本号将会根据Go module的版本选择机制确定一个最优版本。
如何处理间接依赖?
接依赖出现在go.mod中,可以一定程度上说明依赖有瑕疵,要么是其不支持Go module,要么是其go.mod文件不完整。
由于Go 语言从v1.11版本才推出module的特性,众多开源软件迁移到go module还需要一段时间,在过渡期必然会出现间接依赖,但随着时间的推进,在go.mod中出现// indirect的机率会越来越低。
出现间接依赖可能意味着你在使用过时的软件,如果有精力的话还是推荐尽快消除间接依赖。可以通过使用依赖的新版本或者替换依赖的方式消除间接依赖。
如何查找间接依赖来源?
Go module提供了go mod why 命令来解释为什么会依赖某个软件包,若要查看go.mod中某个间接依赖是被哪个依赖引入的,可以使用命令go mod why -m <pkg>来查看。
比如,我们有如下的go.mod文件片断:
require (
github.com/Rican7/retry v0.1.0 // indirect
github.com/google/uuid v1.0.0
github.com/renhongcai/indirect v1.0.0
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/text v0.3.2
)
我们希望确定间接依赖github.com/Rican7/retry v0.1.0 // indirect是被哪个依赖引入的,则可以使用命令go mod why来查看:
[root@wsl-maoyifei]# go mod why -m github.com/Rican7/retry
# github.com/Rican7/retry
github.com/renhongcai/gomodule
github.com/renhongcai/indirect
github.com/Rican7/retry
上面的打印信息中# github.com/Rican7/retry 表示当前正在分析的依赖,后面几行则表示依赖链。github.com/renhongcai/gomodule 依赖github.com/renhongcai/indirect,而github.com/renhongcai/indirect依赖github.com/Rican7/retry。由此我们就可以判断出间接依赖github.com/Rican7/retry是被github.com/renhongcai/indirect引入的。
另外,命令go mod why -m all则可以分析所有依赖的依赖链。
Go依赖包管理--间接依赖的更多相关文章
- bower一个强大的前端依赖包管理工具
在介绍之前,你必须的知道bower是基于nodejs开发的,所以你首先必须得有个nodejs环境,至于这么安装nodejs网上一大堆教程,对了使用bower还需要安装git,这里就不多说了. #### ...
- go依赖包管理工具vendor基础
go依赖包管理工具vendor基础 vendor是go的依赖包管理工具,主要用于管理项目中使用到的一些依赖. 它将项目依赖的包,特指外部包,复制到当前工程下的vendor目录下,这样go build的 ...
- 【转】Mapreduce部署与第三方依赖包管理
Mapreduce部署是总会涉及到第三方包依赖问题,这些第三方包配置的方式不同,会对mapreduce的部署便捷性有一些影响,有时候还会导致脚本出错.本文介绍几种常用的配置方式: 1. HADOOP_ ...
- Mapreduce部署与第三方依赖包管理
Mapreduce部署是总会涉及到第三方包依赖问题,这些第三方包配置的方式不同,会对mapreduce的部署便捷性有一些影响,有时候还会导致脚本出错.本文介绍几种常用的配置方式: 1. HADOOP_ ...
- Go 包管理与依赖查找顺序
目录 1. 规则: 2. 编译时的依赖包查找机制 3.vendor vendor的层级搜索 4. modules 1. 规则: 同一目录下只能存在一个包 目录和目录下源文件的包命名可以不同 当包名与目 ...
- go 依赖包管理工具gb安装报错
尝试了下gb工具,发现有个问题: [root@etcd1 test]# go get github.com/constabulary/gb/... /home/gopath/src/github.co ...
- 在Azure DevOps Server 中提交Maven 依赖包(mvn deploy-file)
Contents 1. 概述 2. 必要准备 安装Java 下载安装Maven 3. 服务器配置 新建连接源 4. 客户端配置 5. 上传maven包文件 6. 常见问题 Maven最新版本3.6.2 ...
- Maven - 实例-2-使用本地仓库中的依赖包
Maven引入构建包的流程 执行mvn compile命令编译源代码,如果编译过程中需要用到其他的包, maven将会在pom.xml文件中查找是否引入该依赖包的坐标. 示例: <depende ...
- idea引入依赖包报错
今天在更新项目的时候,maven依赖的一个服务一直报错.查了后发现原来是因为缺少依赖包.但是依赖包明明在我本地啊. 又重新下载,依然如故... 搞了半天,发现自己的依赖包类状态都是不可用的.如下图所示 ...
随机推荐
- 最近被旷视的YOLOX刷屏了!
目录 论文主要信息 文章概要 背景 YOLOX-DarkNet53 实现细节 YOLOv3 baseline Decoupled head 实验 思路 story Strong data augmen ...
- C语言学习之基本数据类型【一】
近期学习鸿蒙硬件物联网开发,用到的开发语言是C: 一.基础语法:第一个案例: 命令 gcc hello.c #include <stdio.h> //stdio.h 是一个头文件 , #i ...
- odoo14通过命令行启动以及报错进不去系统问题解决办法
一.通过CMD命令界面启动odoo:进入odoo-bin目录下:执行 python odoo-bin -c odoo.conf 二.pycharm配置自动安装升级模块:-c E:\odoo14\od ...
- C++第三十九篇 -- 研究一下Windows驱动开发(二)-- 驱动程序中重要的数据结构
数据结构是计算机程序的核心,I/O管理器定义了一些数据结构,这些数据结构是编写驱动程序时所必须掌握的.驱动程序经常要创建和维护这些数据结构的实例. 一.驱动对象(DRIVER_OBJECT) 每个驱动 ...
- 多项式求值问题(horner规则)——Python实现
# 多项式求值(Horner规则) # 输入:A[a0,a1,a2...an],x的值 # 输出:给定的x下多项式的值p # Horner迭代形式实现 1 # 在此修改初值 2 A = [2, 6 ...
- 离线安装rpm包并解决依赖(升级vsftpd为例)
背景 实际开发中,我们的linux服务器是处理离线状态的,并不能访问互联网.如果此时要在linux上安装或者升级软件,就只能通过rpm包的安装方式.rpm包安装有一个缺陷,就是不能处理安装包的依赖问 ...
- 百度nlp api接口测试
date:2021/7/8 使用postman测试 网址:https://ai.baidu.com/ 在百度AI首页-开放能力-自然语言处理-语言处理基础技术 点击技术文档 在左侧文档目录选择API参 ...
- MSTP
目录 一.生成树存在的问题 二.MSTP 三.MSTP的网络层次 四.MSTP的端口状态 五.MSTP的保护功能 一.生成树存在的问题 STP和RSTP的问题 PVST的问题 二.MSTP 多生成树 ...
- bugku-misc 9-16
宽带信息泄露 拿到一个bin后缀的文件,知道是一个二进制文件,但是题目提到的和宽带有关,flag就是用户名.可以使用RoutePassView这个工具,使用的时候记得关闭杀毒软件. 工具可以在这里下载 ...
- HCIA-网络层包结构
网络层 关心-->转发 IPV4协议 IPV6协议 寻址 转发 标识位置 IPV6: 86DD MAC定位局部 网络定位全局 对于上层数据如果过大,网络层可以分组,实现分组转发 环路:发送了一个 ...