为什么 go.mod 中的所有依赖都是间接的?

huangapple go评论113阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2022年5月9日 01:55:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/72163772.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定