Golang中go mod vendor的间接包问题探讨

Golang中go mod vendor的间接包问题探讨 我有一个使用第三方包的Go项目。这些包位于GitHub上。 构建项目时没有任何问题。

但是,当我运行:

go mod vendor

它只会复制 go.mod 文件中那些不是 // indirect 的包。 我希望“vendoring”我所有的包,这样即使代码库被删除,我也能构建项目。

我知道可以设置一个GOPROXY来解决“代码库被删除”的问题。但对我来说,一个包含所有依赖源代码的vendor目录是可行的。

有什么想法吗?

2 回复

你好(再次)

我找到了一个解决方案,是我的问题。 在构建时:

go build -mod=vendor .

这将使用 vendor 目录中的所有包。这样构建就没有问题了。

更多关于Golang中go mod vendor的间接包问题探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go模块中,go mod vendor 默认只复制直接依赖,而间接依赖(标记为 // indirect)不会被包含到 vendor 目录中。这是 Go 工具链的默认行为,目的是减少 vendor 目录的大小。

如果你需要将所有依赖(包括间接依赖)都复制到 vendor 目录,可以使用 go mod vendor 配合 -v 参数,但它仍然不会包含间接依赖。实际上,Go 并没有直接提供将间接依赖也复制到 vendor 目录的选项。不过,你可以通过以下两种方法来实现:

方法1:使用 go mod tidy 确保所有依赖都是直接依赖

间接依赖通常是因为你的直接依赖没有在 go.mod 中明确声明其依赖。你可以尝试更新或替换这些依赖,使它们成为直接依赖。但这种方法可能不总是可行,尤其是当间接依赖是深层依赖时。

方法2:手动修改 go.mod 文件,将间接依赖变为直接依赖

你可以手动编辑 go.mod 文件,将 // indirect 注释的依赖移动到 require 部分,并移除注释。然后运行 go mod vendor 来复制所有依赖。

例如,假设你的 go.mod 文件中有以下内容:

module example.com/myproject

go 1.21

require (
    github.com/some/direct v1.0.0
)

require (
    github.com/some/indirect v1.0.0 // indirect
)

你可以将 github.com/some/indirect v1.0.0 移动到 require 部分,并移除 // indirect 注释:

module example.com/myproject

go 1.21

require (
    github.com/some/direct v1.0.0
    github.com/some/indirect v1.0.0
)

然后运行:

go mod tidy
go mod vendor

这样,github.com/some/indirect 就会被复制到 vendor 目录中。

方法3:使用脚本自动处理

你可以编写一个脚本,解析 go.mod 文件,将所有间接依赖变为直接依赖。以下是一个简单的 Bash 脚本示例:

#!/bin/bash
# 提取所有依赖(包括间接依赖)
go list -m all | awk 'NR>1 {print $1 "@" $2}' > all_deps.txt

# 更新 go.mod 文件,确保所有依赖都在 require 部分
while read dep; do
    if ! grep -q "$dep" go.mod; then
        go mod edit -require "$dep"
    fi
done < all_deps.txt

# 运行 go mod tidy 和 go mod vendor
go mod tidy
go mod vendor

# 清理临时文件
rm all_deps.txt

这个脚本会列出所有依赖(包括间接依赖),然后将它们添加到 go.mod 文件的 require 部分。之后运行 go mod tidygo mod vendor 来复制所有依赖到 vendor 目录。

方法4:使用第三方工具

有一些第三方工具可以帮助你实现这个目标,例如 modvendorvend。这些工具可以复制所有依赖到 vendor 目录,包括间接依赖。

例如,使用 modvendor

# 安装 modvendor
go install github.com/goware/modvendor@latest

# 复制所有依赖到 vendor 目录
modvendor -copy="**/*.c **/*.h **/*.proto **/*.s" -v

注意:这些工具可能不是官方维护的,使用时需要谨慎。

总结

虽然 go mod vendor 默认不复制间接依赖,但你可以通过手动修改 go.mod 文件、使用脚本或第三方工具来将所有依赖复制到 vendor 目录。这样即使远程代码库被删除,你仍然可以构建项目。不过,需要注意的是,vendor 目录可能会变得很大,因为它包含了所有依赖的源代码。

回到顶部