Why does `go list -mod=readonly -m all` require access to private repos?

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

Why does `go list -mod=readonly -m all` require access to private repos?

问题

我正在尝试打印一个带有vendor目录的Go项目中的直接依赖项列表,命令如下:

go list -mod=readonly -m -f '{{ if not .Indirect }}{{ .Path }}{{ end }}' all

据我了解,我必须使用-mod=readonly,因为go list拒绝根据vendor中的部分信息报告依赖项(参考:https://github.com/golang/go/blob/master/src/cmd/go/internal/list/list.go#L508_L513)。这在我的笔记本电脑上可以工作,因为我可以访问私有仓库github.com/monzo/argo-rollouts,但在CI中会失败,错误信息如下:

go list -m: github.com/argoproj/argo-rollouts@v0.0.0-20220309162305-84c86ea52e8f (replaced by github.com/monzo/argo-rollouts@v0.0.0-20220309162305-84c86ea52e8f): version "v0.0.0-20220309162305-84c86ea52e8f" invalid: git fetch -f origin refs/heads/*:refs/heads/* refs/tags/*:refs/tags/* in /home/circleci/go/pkg/mod/cache/vcs/052bf06be1713582ba9f1144e9982b362ff355fec71675863c108f9cf5a00bb4: exit status 128:
	ERROR: Repository not found.
	fatal: Could not read from remote repository.
	
	Please make sure you have the correct access rights
	and the repository exists.

为什么go list -mod=readonly需要访问私有仓库?我没有提供-u参数。

另外,在vendor模式下,为什么它无法在本地获取这些信息?

编辑:我找到了一个解决方法,可以将符合条件的模块传递给go list -m在vendor模式下使用,但这涉及解析供机器使用的不稳定的vendor/modules.txt文件。

% cat modules-that-provide-packages.awk
BEGIN {
        mod = ""
}

# 记住模块
/^# / {
        mod = $2
}

# 如果模块提供了一个包,则打印模块
!/^# / {
        print mod
}


% awk -f modules-that-provide-packages.awk vendor/modules.txt / | sort -u | xargs go list -m -f '{{ if not .Indirect }}{{ .Path }}{{ end }}'
英文:

I'm trying to print a list of direct dependencies in a Go project that has a vendor directory with:

go list -mod=readonly -m -f '{{ if not .Indirect }}{{ .Path }}{{ end }}' all

As I understand, I have to use -mod=readonly because go list refuses to report based on the partial information in vendor. This works on my laptop, because I have access to the private repo github.com/monzo/argo-rollouts, but in CI it fails with:

go list -m: github.com/argoproj/argo-rollouts@v0.0.0-20220309162305-84c86ea52e8f (replaced by github.com/monzo/argo-rollouts@v0.0.0-20220309162305-84c86ea52e8f): version "v0.0.0-20220309162305-84c86ea52e8f" invalid: git fetch -f origin refs/heads/*:refs/heads/* refs/tags/*:refs/tags/* in /home/circleci/go/pkg/mod/cache/vcs/052bf06be1713582ba9f1144e9982b362ff355fec71675863c108f9cf5a00bb4: exit status 128:
	ERROR: Repository not found.
	fatal: Could not read from remote repository.
	
	Please make sure you have the correct access rights
	and the repository exists.

Why does go list -mod=readonly need access to the private repo? I haven't provided -u.

Also, why can't it get this information locally when in vendor mode?

Edit: I've found a workaround that passes eligible modules to go list -m in vendor-mode, but it involves parsing the unstable vendor/modules.txt file intended for machines only.

% cat modules-that-provide-packages.awk
BEGIN {
        mod = ""
}

# Remember the module
/^# / {
        mod = $2
}

# Print the module if it provides a package
!/^# / {
        print mod
}


% awk -f modules-that-provide-packages.awk vendor/modules.txt /
    | sort -u \
    | xargs go list -m -f '{{ if not .Indirect }}{{ .Path }}{{ end }}'

答案1

得分: 1

我认为答案是:go list -m 不需要访问私有仓库,但是需要填充空的 GOMODCACHE

go list -m 从以下位置获取模块信息:

  • GOMODCACHE,但是这个位置必须已经填充。在 CI 中它是空的,所以 Go 会尝试从私有仓库下载,因此会出现错误。
  • vendor 目录,但是你必须提供一个具体的模块。go list -m all 在 vendor 模式下会放弃(参考链接:https://github.com/golang/go/blob/master/src/cmd/go/internal/list/list.go#L508_L513)。
英文:

I think the answer is: go list -m doesn't require access to private repos, but populating an empty GOMODCACHE does.

go list -m gets the module info from either:

  • GOMODCACHE, but this must be already populated. It is empty in CI, so Go will try to download from the private repos. Hence the error.
  • The vendor directory, but you must provide a specific module. go list -m all gives up in vendor-mode.

答案2

得分: 0

  • 确保在你的 CI 脚本中将 GOPRIVATE 设置为你的私有 GitHub 账户链接,例如 github.com/abc*
  • 添加 git 配置,使用 GitHub 账户令牌登录私有仓库。在你的 CI 中,你需要在 CI 脚本中执行类似以下的操作:
git config --global url."https://${{ inputs.token }}:x-oauth-basic@github.com/<useraccount>".insteadOf "https://github.com/<useraccount>"
  • 现在当你运行该命令时,它将能够访问私有仓库,或者在运行列表命令之前,确保先执行 go mod vendor 命令,在 CI 上获取所有的依赖项。
英文:
  • make sure you set GOPRIVATE to your private GitHub account link eg github.com/abc* in your CI script
  • Add git config to use the GitHub account token to log in to the private repo. On your ci, you would have to do something like this in the CI script
 git config --global url.&quot;https://${{ inputs.token }}:x-oauth-basic@github.com/&lt;useraccount&gt;&quot;.insteadOf &quot;https://github.com/&lt;useraccount&gt;&quot;

  • Now when you run the command it will be able to access the private repo or before running the list command make sure to do go mod vendor to get all the dependencies on CI first

huangapple
  • 本文由 发表于 2022年6月30日 20:47:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/72816128.html
匿名

发表评论

匿名网友

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

确定