- go 版本管理器(g)源码阅读笔记(一个 go 版本管理工具)
- 原文作者:suhanyujie
- 文章来自:https://github.com/suhanyujie/article-transfer-rs/
- ps:水平有限,如有不当之处,欢迎指正。
- 标签:go 版本管理器,Go,版本管理器
g 是 go 的一个命令行程序,主要用于 go 的本地版本管理。比如,你要同时开发两个 go 项目,一个是 go1.17 版本,另一个是 go1.18 版本,这个时候,比较好的选择就是用 g。
g 的简单使用
在这篇笔记中,我打算逐个了解一下 g 主要命令的使用,然后针对该主要用法的实现去剖析,了解学习实现原理。
g 的安装可以直接参考官方仓库的 readme 文档,其中描述的很详细,这里就不再赘述。
查询可用版本的 go
安装完成后,我们可以通过 g ls-remote stable
查看可用的 go 版本:
$ g ls-remote stable
1.17.9
* 1.18.1
它列出来当前最新的两个稳定版。
实现分析
g 程序的入口很简单只有一行代码:
cli.Run()
Run 函数定义在 cli 包中。通过依赖可以看出,它的实现是基于 github.com/urfave/cli/v2
,这是一个专门用于写命令行程序的包。通过它,实例化一个 app,并初始化应用的名称、版本、作者等基础信息以及命令执行前要做的操作:
app := cli.NewApp()
app.Name = "g"
app.Usage = "Golang Version Manager"
// 省略片段 ...
app.Before = func(ctx *cli.Context) (err error) {
ghomeDir = ghome()
goroot = filepath.Join(ghomeDir, "go")
downloadsDir = filepath.Join(ghomeDir, "downloads")
if err = os.MkdirAll(downloadsDir, 0755); err != nil {
return err
}
versionsDir = filepath.Join(ghomeDir, "versions")
return os.MkdirAll(versionsDir, 0755)
}
通常情况下,一个命令行程序可以根据输入的参数而执行不同的操作,比如 git add
, git commit
等,这里的 g 程序也是类似,也就是说根据输入参数不同,需要有对应的 handlers,所以就有了 commands: