英文:
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 eggithub.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."https://${{ inputs.token }}:x-oauth-basic@github.com/<useraccount>".insteadOf "https://github.com/<useraccount>"
- 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论