Go Module 工程化实践(二):go get 取包原理篇

栏目: 编程工具 · 发布时间: 5年前

内容简介:接上篇:不论是否开启假设依赖包

接上篇: Go Module 工程化实践(一):基础概念篇

2. go get 取包原理篇

不论是否开启 Go Module 功能, go get 从版本控制系统 VCS 中取包的基础过程是类似的,除了在新的实现中不再循环拉取 submodule 子模块以外。

2.1 go get 基础取包流程

假设依赖包 github.com/liujianping/foo 不在本地,需要通过 go get 获取。发起以下命令:

$: go get github.com/liujianping/foo

命令发出后:

2.1.1 第一步,正则匹配出依赖包的查询路径

go get 可以指定具体包的 import 路径或者通过其自行分析代码中的 import 得出需要获取包的路径。但是 import 路径,并不直接就是该包的查询路径。在 go get 的源码实现中,包的查询路径是通过一组正则匹配出来的。也就是说, import 路径是必须匹配这组正则表达式的,如果不匹配的话,代码是肯定无法编译的。笔者就贴一下这组正则表达式中的github正则与私有仓库的正则:

// Github
    {
        prefix: "github.com/",
        re:     `^(?P<root>github\.com/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(/[\p{L}0-9_.\-]+)*$`,
        vcs:    "git",
        repo:   "https://{root}",
        check:  noVCSSuffix,
    },
    
    //省略其它VCS...
    
    // General syntax for any server. 
    // Must be last.私有仓库将会使用该正则
    {
        re:   `^(?P<root>(?P<repo>([a-z0-9.\-]+\.)+[a-z0-9.\-]+(:[0-9]+)?(/~?[A-Za-z0-9_.\-]+)+?)\.(?P<vcs>bzr|fossil|git|hg|svn))(/~?[A-Za-z0-9_.\-]+)*$`,
        ping: true,
    },

以包路径 github.com/liujianping/foo 为例,正则匹配后,得出的查询路径就是:

https://github.com/liujianping/foo

再结合 go-get 参数,向远端VCS系统发起 https://github.com/liujianping/foo?go-get=1 请求。

2.1.2 第二步,查询得出包的远端仓库地址

包的远端仓库地址,可以通过 go get 请求的响应中的 go-import 的meta标签中的content中获取的。

$: curl https://github.com/liujianping/foo?go-get=1 | grep go-import
<meta name="go-import" content="github.com/liujianping/foo git https://github.com/liujianping/foo.git">

例子中的包对应的远端仓库地址就是: https://github.com/liujianping/foo.git .

2.1.3 第三步,根据仓库地址 clone 到本地

虽然版本控制系统 VCS 本身就存在各类区别,但是一些基础操作大多类似。在 go get 中具体 clone 的过程会根据具体的 VCS 采用对应的操作。

2.2 go get 代理取包流程

了解了 go get 取包的基础流程后,说说 Go Module 功能开启后的完整流程。

开启 Go Module 后, go get 增加了一个新的环境变量 GOPROXY 。该环境变量一旦开启, go get 就完全切换到新的取包流程,即 GOPROXY 流程 ,暂时就这么称呼吧。

GOPROXY 流程 中,官方定义了一组代理接口, 请参考 官方接口定义

GET $GOPROXY/<module>/@v/<version>.info returns JSON-formatted metadata about that version of the given module.
GET $GOPROXY/<module>/@v/<version>.mod returns the go.mod file for that version of the given module.
GET $GOPROXY/<module>/@v/<version>.zip returns the zip archive for that version of the given module.

其实这组接口的定义就是 $GOPATH/pkg/mod/cache/download 中的文件系统。就是说,我们可以直接将此目录下的文件系统作为代理使用,如下命令: export GOPROXY=file:///$GOPATH/pkg/mod/cache/download/

关于 GOPROXY 代理服务,网上有很多实现,官方也推荐了几个。各有各的问题,只能这样说。因为,对于一些定制话的需求,例如:

  • 私有仓库的权限问题
  • 个别库的镜像国内无法访问等

尚无完美的解决方案。但是即使这样,我们还是可以根据具体的工程化需求构建企业内部的一套标准的 GO Module 流程来。具体方案,在下一篇 工程实践篇 中讲解。

2.3 私有仓库取包过程中的常见问题

私有仓库的取包过程中出现的问题大多集中在基础取包过程中。具体的异常又可能发生在2.1.1~2.1.3任一阶段。分别列举常见问题与解决思路。

2.3.1 私有仓库 clone 阶段的权限问题

通常情况下,私有仓库的访问是基于账号权限的。例如, private.vcs.com/group/foo 的包路径,在 go get 过程中,会正则匹配出 https://private.vcs.com/group/foo.git 的仓库路径,假设VCS系统是gitlab搭建的。

那么在 git clone https://private.vcs.com/group/foo.git 的过程中,系统会提醒用户提供用户名与登录密码。每次输入就会很累赘。

解决方案有二:

  • 方法一:
增加 $HOME/.gitconfig 配置:

[url "ssh://git@github.com/MYORGANIZATION/"]

insteadOf = https://github.com/MYORGANIZA...

将原有的https访问方式替换成ssh方式。

  • 方法二:
增加 $HOME/.netrc :

machine github.com login YOU password APIKEY

将其中的 APIKEY 换成自己的登录KEY。

虽然采用的github为例,但适用于gitlab服务。其实,还有一种解决方案,该方案,还能解决2.3.2中的问题,故在下节中讲解。

2.3.2 私有VCS非标路径问题

由于历史原因,笔者公司的gitlab服务地址就是非标准的路径,标准路径应该是: https://private.vcs.com ,而笔者公司的gitlab路径则是: https://private.vcs.com:888 .

如果按 go get 流程,import包路径应该采用d: private.vcs.com:888/group/foo ,就可以正确匹配出该仓库的合理地址了。但是很不幸,在实际操作中,失败告终。具体原因读者可以自行测试一下。

此时唯一的办法,就是搭建一个中间服务: https://private.vcs.com 能够通过 go get 的包路径匹配查询正确的仓库地址。

其实该中间服务器的实现就非常简单。具体实现,笔者留到下一偏: 工程实践篇 讲解。


以上所述就是小编给大家介绍的《Go Module 工程化实践(二):go get 取包原理篇》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数文明

数文明

涂子沛 / 中信出版集团 / 2018-9 / 88.00元

从量数、据数、普适记录、人脸识别、以图搜车,到雾计算、城市大脑、单粒度治理、无匿名社会、量子思维……作为中国研究大数据的权威专家,作者在《数文明》一书中,以大数据为核心元素,抽丝剥茧,深入地阐述了这个大数据时代的文明社会——一个全新的数文明时代。 将大数据与人类文明融合在一起,这本书提供给我们的不仅是一种全新的叙事结构,它还将突破你的认知边界和思维极限,给你提供一个应对这个世界的全新的认知方......一起来看看 《数文明》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具