英文:
Why are all dependency in go.mod indirect?
问题
我通过运行以下命令来初始化一个Go项目:
go mod init firstgo_app
我确认模块已创建:
cat go.mod
module firstgo_app
go 1.18
然后,我通过执行以下命令在github.com/gin-gonic/gin上安装了一个依赖项:
go get github.com/gin-gonic/gin
之后,我查看了go.mod的内容,这次它看起来是这样的:
cat go.mod
module firstgo_app
go 1.18
require (
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/gin-gonic/gin v1.7.7 // indirect
github.com/go-playground/locales v0.13.0 // indirect
github.com/go-playground/universal-translator v0.17.0 // indirect
github.com/go-playground/validator/v10 v10.4.1 // indirect
github.com/golang/protobuf v1.3.3 // indirect
github.com/json-iterator/go v1.1.9 // indirect
github.com/leodido/go-urn v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.12 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect
github.com/ugorji/go/codec v1.1.7 // indirect
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 // indirect
gopkg.in/yaml.v2 v2.2.8 // indirect
)
我不明白的是所有的依赖项都被标记为_indirect_。我的理解是只有传递性依赖项才会被标记为_indirect_,而我直接依赖的依赖项不应该被标记为_indirect_。也就是说,github.com/gin-gonic/gin v1.7.7 // indirect不应该有_indirect_标记,因为这是我特别下载的依赖项。
我认为这是因为我没有直接使用该依赖项,所以我重新创建了模块,同时创建了一个main.go文件,在其中明确依赖于gonic/gin:
cat main.go
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run() // listen and serve on 0.0.0.0:8080
}
当我尝试构建时,出现错误:
go build
main.go:2:8: no required module provides package github.com/gin-gonic/gin; to add it:
go get github.com/gin-gonic/gin
但是,当我运行go get github.com/gin-gonic/gin,然后构建时,go.mod中的所有依赖项仍然被标记为indirect。
所以是什么原因呢?我在这里漏掉了什么?或者我对_indirect_的理解有误?
英文:
I initialise a go project by running:
go mod init firstgo_app
I confirmed the module was created:
cat go.mod
module firstgo_app
go 1.18
Then I installed a dependency on github.com/gin-gonic/gin by executing
get github.com/gin-gonic/gin
after which I viewed the content of go.mod and this time it looks like this:
cat go.mod
module firstgo_app
go 1.18
require (
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/gin-gonic/gin v1.7.7 // indirect
github.com/go-playground/locales v0.13.0 // indirect
github.com/go-playground/universal-translator v0.17.0 // indirect
github.com/go-playground/validator/v10 v10.4.1 // indirect
github.com/golang/protobuf v1.3.3 // indirect
github.com/json-iterator/go v1.1.9 // indirect
github.com/leodido/go-urn v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.12 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect
github.com/ugorji/go/codec v1.1.7 // indirect
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 // indirect
gopkg.in/yaml.v2 v2.2.8 // indirect
)
What I do not get is the fact that all the dependency has been tagged as indirect. My understanding is that it is only transitive dependency that are tagged indirect but the dependency I directly depend upon should not be tagged as such. That is github.com/gin-gonic/gin v1.7.7 // indirect should not have the indirect tag since this is the dependency I specifically downloaded.
I thought this was the case because I am not directly using the dependency, so I recreated the module again but also created a main.go file where I explicitly depend on gonic/gin:
cat main.go
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run() // listen and serve on 0.0.0.0:8080
}
When I try to build it fails with:
go build
main.go:2:8: no required module provides package github.com/gin-gonic/gin; to add it:
go get github.com/gin-gonic/gin
but when I run go get github.com/gin-gonic/gin and then build, all the dependency in go.mod are still tagged indirect.
So what gives? What am I missing here? Or do I understand the indirect wrongly?
答案1
得分: 18
你的理解是正确的。indirect注释表示一个依赖项不是直接被你的模块使用的,而是被其他模块依赖间接使用的。
当你首次运行go get github.com/gin-gonic/gin时,该模块将被下载,但由于你没有使用它,它仍然会被标记为indirect。
当你开始使用它时,它将不再是indirect,但是go build不会自动更新go mod。
运行go mod tidy,然后它将不再被标记为indirect。
$ go mod tidy
$ cat go.mod
module firstgo_app
go 1.18
require github.com/gin-gonic/gin v1.7.7
require (
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.13.0 // indirect
github.com/go-playground/universal-translator v0.17.0 // indirect
github.com/go-playground/validator/v10 v10.4.1 // indirect
github.com/golang/protobuf v1.3.3 // indirect
github.com/json-iterator/go v1.1.9 // indirect
github.com/leodido/go-urn v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.12 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect
github.com/ugorji/go/codec v1.1.7 // indirect
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 // indirect
gopkg.in/yaml.v2 v2.2.8 // indirect
)
这是自Go 1.14以来的情况:
> 如果更改只是表面上的,go mod tidy之外的go命令将不再编辑go.mod文件。
英文:
Your understanding is correct. The indirect comment indicates a dependency is not used directly by your module, only indirectly by other module dependencies.
When you first run go get github.com/gin-gonic/gin, the module will be downloaded, but since you don't use it, it will still be marked indirect.
When you start using it, it will no longer be indirect, but go build does not update go mod automatically.
Run go mod tidy, and then it will not be marked indirect anymore.
$ go mod tidy
$ cat go.mod
module firstgo_app
go 1.18
require github.com/gin-gonic/gin v1.7.7
require (
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.13.0 // indirect
github.com/go-playground/universal-translator v0.17.0 // indirect
github.com/go-playground/validator/v10 v10.4.1 // indirect
github.com/golang/protobuf v1.3.3 // indirect
github.com/json-iterator/go v1.1.9 // indirect
github.com/leodido/go-urn v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.12 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect
github.com/ugorji/go/codec v1.1.7 // indirect
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 // indirect
gopkg.in/yaml.v2 v2.2.8 // indirect
)
This has been since Go 1.14:
> go commands other than go mod tidy no longer edit the go.mod file if the changes are only cosmetic.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论