Go填坑之将Private仓库用作module依赖

本文同步发布于个人博客

Golang的发展可以用日新月异来形容,但是这并非褒义词,而是说它在性能、功能上存在诸多不完善之处,相同的功能伴随着小版本的发展,也会出现破坏性的变化。

但是既然选择了Golang,无论合不合理,我们都不得不忍受Russ Cox对该语言天马行空、大刀阔斧的变更。

本文简单介绍一下Go语言在1.11版本之后推出的go mod使用私有仓库时遇到的问题。

直接使用go get

直接使用go get ...添加私有仓库依赖时,会出现以下错误:

get "gitlab.com/xxx": found meta tag get.metaImport{Prefix:"gitlab.com/xxx", VCS:"git", RepoRoot:"https://gitlab.com/xxx.git"} at //gitlab.com/xxx?go-get=1
go get gitlab.com/xxx: git ls-remote -q https://gitlab.com/xxx.git in /Users/sulin/go/pkg/mod/cache/vcs/91fae55e78195f3139c4f56af15f9b47ba7aa6ca0fa761efbd5b6e2b16d5159d: exit status 128:
    fatal: could not read Username for 'https://gitlab.com': terminal prompts disabled
Confirm the import path was entered correctly.
If this is a private repository, see https://golang.org/doc/faq#git_https for additional information.

从错误信息可以明显地看出来,我们使用私有仓库时通常会配置ssh-pubkey进行鉴权,但是go get使用https而非ssh的方式来下载依赖,从而导致鉴权失败。

GOPROXY错误

如果配置了GOPROXY代理,错误信息则是如下样式:

go get gitlab.com/xxx: module gitlab.com/xxx: reading https://goproxy.io/gitlab.com/xxx/@v/list: 404 Not Found

从错误信息可以看出,go get通过代理服务拉取私有仓库,而代理服务当然不可能访问到私有仓库,从而出现了404错误。

1.12版本解决方案

1.111.12版本中,比较主流的解决方案是配置git强制采用ssh

这个解决方案在许多博客、问答中都可以看到:

git config --global url."git@gitlab.com:xxx/zz.git".insteadof "https://gitlab.com/xxx/zz.git"

但是它与GOPROXY存在冲突,也就是说,在使用代理时,这个解决方案也是不生效的。

1.13版本解决方案

1.13版本之后,前面介绍的解决方案又会导致go get出现另一种错误:

get "gitlab.com/xxx/zz": found meta tag get.metaImport{Prefix:"gitlab.com/xxx/zz", VCS:"git", RepoRoot:"https://gitlab.com/xxx/zz.git"} at //gitlab.com/xxx/zz?go-get=1
  verifying gitlab.com/xxx/zz@v0.0.1: gitlab.com/xxx/zz@v0.0.1: reading https://sum.golang.org/lookup/gitlab.com/xxx/zz@v0.0.1: 410 Gone

这个错误是因为新版本go mod会对依赖包进行checksum校验,但是私有仓库对sum.golang.org是不可见的,它当然没有办法成功执行checksum

也就是说强制git采用ssh的解决办法在1.13版本之后GG了。

当然Golang在堵上窗户之前,也开了大门,它提供了一个更方便的解决方案:GOPRIVATE环境变量。解决以上的错误,可以这样配置:

export GOPRIVATE=gitlab.com/xxx

它可以声明指定域名为私有仓库,go get在处理该域名下的所有依赖时,会直接跳过GOPROXYCHECKSUM等逻辑,从而规避掉前文遇到的所有问题。

另外域名gitlab.com/xxx非常灵活,它默认是前缀匹配的,所有的gitlab.com/xxx前缀的依赖模块都会被视为private-modules,它对于企业、私有Group等有着一劳永逸的益处。

提示:如果你通过ssh公钥访问私有仓库,记得配置git拉取私有仓库时使用ssh而非https

可以通过命令git config ...的方式来配置。也可以像我这样,直接修改~/.gitconfig添加如下配置:

[url "git@github.com:"]
    insteadOf = https://github.com/
[url "git@gitlab.com:"]
    insteadOf = https://gitlab.com/

即可强制go get针对github.comgitlab.com使用ssh而非https

后续版本

未来可能会有其他的变化,如果出现了的话,我会继续完善这篇文章。

顺便为自己写的日志库slf4go打个广告。


西西弗苏
记录我的技术研究,分享我的开源项目,文章同步发布在个人网站sulin.me中。
77 声望
6 粉丝
0 条评论
推荐阅读
一切皆有可能——Golang中的“ThreadLocal”库
本文介绍的是新写的routine库,它封装并提供了一些易用、高性能的goroutine上下文访问接口,可以帮助你更优雅地访问协程上下文信息,但你也可能就此打开了潘多拉魔盒。

sisyphsu4阅读 7.1k评论 1

「刷起来」Go必看的进阶面试题详解
逃逸分析是Go语言中的一项重要优化技术,可以帮助程序减少内存分配和垃圾回收的开销,从而提高程序的性能。下面是一道涉及逃逸分析的面试题及其详解。

王中阳Go4阅读 1.9k评论 1

封面图
初学后端,如何做好表结构设计?
这篇文章介绍了设计数据库表结构应该考虑的4个方面,还有优雅设计的6个原则,举了一个例子分享了我的设计思路,为了提高性能我们也要从多方面考虑缓存问题。

王中阳Go4阅读 1.7k评论 2

封面图
滚蛋吧,正则表达式!
你是不是也有这样的操作,比如你需要使用「电子邮箱正则表达式」,首先想到的就是直接百度上搜索一个,然后采用 CV 大法神奇地接入到你的代码中?

良许4阅读 2.3k

又一款眼前一亮的Linux终端工具!
今天给大家介绍一款最近发现的功能十分强大,颜值非常高的一款终端工具。这个神器我是在其他公众号文章上看到的,但他们都没把它的强大之处介绍明白,所以我自己体验一波后,再向大家分享自己的体验。

良许5阅读 1.8k

一分钟搞明白!快速掌握 Go WebAssembly
最近因为各种奇怪的原因,更多的接触到了 WebAssembly。虽然之前很多博客也翻过写过各种文章,但总感觉欠些味道。于是今天梳理了一版,和大家一起展开学习。

煎鱼4阅读 2.1k

面试官:请说一下如何优化结构体的性能?
使用内存对齐机制优化结构体性能,妙啊!前言之前分享过2篇结构体文章:10秒改struct性能直接提升15%,产品姐姐都夸我好棒 和 Go语言空结构体这3种妙用,你知道吗? 得到了大家的好评。这篇继续分享进阶内容:结...

王中阳Go4阅读 3.8k评论 2

封面图
77 声望
6 粉丝
宣传栏