`cmd/go: 1.17 go mod tidy` 产生的 `go.mod` 文件无法与 `go mod graph` 一起使用,以理解依赖项的来源,

dfddblmv  于 8个月前  发布在  Go
关注(0)|答案(6)|浏览(75)

你正在使用哪个版本的Go( go version )?

$ go version
go version go1.17rc2 darwin/amd64

这个问题在最新版本中是否会重现?

是的

你正在使用什么操作系统和处理器架构( go env )?

go env 输出

$ go env

GO111MODULE=""

GOARCH="amd64"

GOBIN=""

GOCACHE="/Users/liggitt/Library/Caches/go-build"

GOENV="/Users/liggitt/Library/Application Support/go/env"

GOEXE=""

GOEXPERIMENT=""

GOFLAGS=""

GOHOSTARCH="amd64"

GOHOSTOS="darwin"

GOINSECURE=""

GOMODCACHE="/Users/liggitt/go/pkg/mod"

GONOPROXY=""

GONOSUMDB=""

GOOS="darwin"

GOPATH="/Users/liggitt/go"

GOPRIVATE=""

GOPROXY=" [https://proxy.golang.org,direct](https://proxy.golang.org,direct) "

GOROOT="/Users/liggitt/.gvm/gos/go1.17rc2"

GOSUMDB="sum.golang.org"

GOTMPDIR=""

GOTOOLDIR="/Users/liggitt/.gvm/gos/go1.17rc2/pkg/tool/darwin_amd64"

GOVCS=""

GOVERSION="go1.17rc2"

GCCGO="gccgo"

AR="ar"

CC="clang"

CXX="clang++"

CGO_ENABLED="1"

GOMOD="/Users/liggitt/go/src/k8s.io/kubernetes/go.mod"

CGO_CFLAGS="-g -O2"

CGO_CPPFLAGS=""

CGO_CXXFLAGS="-g -O2"

CGO_FFLAGS="-g -O2"

CGO_LDFLAGS="-g -O2"

PKG_CONFIG="pkg-config"

GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/7f/9xt_73f12xlby0w362rgk0s400kjgb/T/go-build1198370725=/tmp/go-build -gno-record-gcc-switches -fno-common"

你做了什么?

从讨论#46366中提升(评论)
整理了一个具有直接和间接依赖关系的模块,并运行了基于 go mod graph 的依赖统计检查工具。

go mod init example

echo '
package main

import (
"fmt"
"github.com/liggitt/tidy-117/b"
)

func main() {
fmt.Println(b.Do())
}
' > main.go

go mod tidy

go mod graph

你期望看到什么?

有用的模块图输出。
go1.16会产生这样的结果:

example github.com/liggitt/tidy-117/b@v1.0.0
github.com/liggitt/tidy-117/b@v1.0.0 github.com/liggitt/tidy-117/c@v1.0.0

你看到了什么?

go1.17rc2会产生这样的结果:

example github.com/liggitt/tidy-117/b@v1.0.0
example github.com/liggitt/tidy-117/c@v1.0.0
github.com/liggitt/tidy-117/b@v1.0.0 github.com/liggitt/tidy-117/c@v1.0.0

这显示了一条从 example → github.com/liggitt/tidy-117/c 发出的边,实际上并不存在......它只通过 github.com/liggitt/tidy-117/b 是传递性的。
go mod graph 目前对于理解整洁依赖项的子树非常有用,并且可以将其管道到诸如dot之类的图形可视化工具中,以找到减少依赖关系的可能性。
1.17对 go mod tidy 的更改添加了边,使得 go mod graph 不适合用于此目的。

brccelvz

brccelvz1#

cc @bcmills@jayconrod@dims

niwlg2el

niwlg2el2#

整理了一个具有直接和间接依赖关系的模块,并根据 go mod graph 运行了依赖统计检查工具。
...
go mod tidy 的 1.17 版本中的更改添加了边,使得 go mod graph 不适合用于此目的。
我认为 go mod graph 从来就不太适合计算直接与间接依赖关系统计。它的主要用途是帮助您确定为什么选择了特定的版本,而不是该版本与模块内的包有何关联。
go 1.17 模块添加的依赖边也可能在其他模块中出现,当传递依赖项升级到本应被选择的版本以上时。因此,“显式”等于“直接”的假设已经相当脆弱(它并不一定成立,尽管在实践中可能对许多项目适用)。

wswtfjt7

wswtfjt73#

我们今天用于分析为什么需要依赖项的工具是 go mod why(和 go mod why -m)以及 go list。还有一些基于这些工具构建的第三方工具,提供更多的结构并支持更详细的查询。(例如,今天早上在 Gophers Slack 上的一些人推荐了 goda。我自己没有使用过,但它似乎支持一个相当合理的查询语言。)

kmynzznz

kmynzznz4#

在Go 1.17模块中添加的依赖关系边也可能随时出现在其他模块中,当传递依赖关系升级到原本会被选择的版本以上时。
明白了,但在这种情况下,模块对传递依赖关系有明确的意见,所以表示一条边是有意义的。
我认为不幸的是,我们之前使用go mod tidygo mod graph免费获得的图表示,现在我们必须从go list的输出中重新构建。

daolsyd0

daolsyd05#

我们今天用于分析为什么需要依赖项的工具是 go mod why (和 go mod why -m) 以及 go list。
在 kubernetes/kubernetes#104461 中讨论切换到使用 go list,看起来由于 go list 是 build-tag 受限制的,它不包括所有告知 go mod tidygo mod vendor 的包/模块。这是准确的吗?有没有办法使用 go list 从所有 build 标签中获取完整的依赖项集?

q9rjltbz

q9rjltbz6#

go list 确实是受标签约束的。(#42504 跟踪解决该任务的工作。)

相关问题