Go的间接依赖
为什么已经在module/项目中使用go mod download下来所需依赖了,但是之后运行go 命令仍然出现了缺少依赖的错误
- 问题来源:
[root@192 helloworld]# go generate ./...
/root/go/pkg/mod/github.com/google/wire@v0.5.0/cmd/wire/main.go:34:2: missing go.sum entry for module providing package github.com/google/subcommands (imported by github.com/google/wire/cmd/wire); to add:
go get github.com/google/wire/cmd/wire@v0.5.0
/root/go/pkg/mod/github.com/google/wire@v0.5.0/internal/wire/copyast.go:21:2: missing go.sum entry for module providing package golang.org/x/tools/go/ast/astutil (imported by github.com/google/wire/internal/wire); to add:
go get github.com/google/wire/internal/wire@v0.5.0
/root/go/pkg/mod/github.com/google/wire@v0.5.0/internal/wire/parse.go:30:2: missing go.sum entry for module providing package golang.org/x/tools/go/packages (imported by github.com/google/wire/internal/wire); to add:
go get github.com/google/wire/internal/wire@v0.5.0
/root/go/pkg/mod/github.com/google/wire@v0.5.0/internal/wire/analyze.go:26:2: missing go.sum entry for module providing package golang.org/x/tools/go/types/typeutil (imported by github.com/google/wire/cmd/wire); to add:
go get github.com/google/wire/cmd/wire@v0.5.0
cmd/helloworld/wire_gen.go:3: running "go": exit status 1
我使用kratos新建了一个helloworld项目,并且运行了go mod download
下载依赖包,并且之后查看了~/go/pkg/mod/目录,感觉一切正常,
但是在执行go generate ./...
命令的时候却出现了上述报错
其中go generate会自动去执行go run github.com/google/wire/cmd/wire
,这是源自项目中一个go generate注释:
// Code generated by Wire. DO NOT EDIT.
//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
import (
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/log"
"helloworld/internal/biz"
"helloworld/internal/conf"
"helloworld/internal/data"
"helloworld/internal/server"
"helloworld/internal/service"
)
这么一看是缺少了github.com/google/subcommands
以及wire依赖的其他的几个包,但是事实上我项目中的go.mod
文件以及项目中的代码中均有引入github.com/google/wire
这个包进行使用,而subcommands这几个包作为wire的依赖包却没有被安装进来
解决办法:
上述报错提到依赖github.com/google/subcommands
的包是github.com/google/wire/cmd/wire
,go提供了一个命令go mod why packageName
用于查看这个包的依赖项,也就是看具体是谁依赖了这个包,比如go.mod文件下也有很多间接依赖,后面打上了 //indirect注释,
这个时候就可以通过go mod why
来查看到底是哪个包依赖了它的,所以这里我们也使用why命令来检查github.com/google/wire/cmd/wire
,
得到:
[root@192 helloworld]# go mod why github.com/google/wire/cmd/wire
# github.com/google/wire/cmd/wire
(main module does not need package github.com/google/wire/cmd/wire)
发现居然没有包用到它,查看它的源码发现,这个目录下面只有一个main.go,进一步检查前往github.com/google/wire
这个包去全文搜索发现,整个项目其实没有一处require这个包的,加上go generate这个命令后面的命令发现,也就是说这个包只是通过在命令行直接使用go run github.com/google/wire/cmd/wire来使用的。
而golang中对于依赖下载的这个特性是1.17之后加上的,名为修剪依赖,指的是如果没有被主模块使用到的包,将不会被加载
参考资料: