本文谈下我对 Go 版本管理的一些思考,并给你们介绍一个小工具,gvm。这个话题提及来也很简单,但若是想用的爽,仍是要稍微梳理下。github
Go 的版本管理,并不是包的依赖管理。平时的工做中,不少时候并不会遇到这样的需求,因此可能并非很明白它的价值。golang
简单说下我写这篇文章的背景吧。web
最近几周,Go 最重要的一则消息应该莫过 9月份 Go 1.13 的正式发布。它的相关升级可查看 Go 1.13 正式发布,看看都有哪些值得关注的特性 或官方 Go 1.13 Relase Notes。shell
对于一名 gopher 而言,可能早已按捺不住本身那颗躁动的心,想尽快体验下新版的升级项。但问题是,切换至新版 Go 一般会遇到一些问题,好比不一样版本的环境配置,安装的辅助工具和程序包在不一样版本下可能会存在兼容或被覆盖等问题。bash
我天然就但愿有一套方案能够帮助我完成 Go 版本的切换,实现不一样版本间环境的彻底隔离。markdown
谈到环境隔离,有不少方案可供选择,如多主机、虚拟机、容器等技术。这些听起来都挺不错,都能实现需求。但若是只是为了 Go 版本管理,彻底能够本身实现。网络
多版本切换,主要是不一样版本环境变量的隔离。Go 1.10 以前,咱们关心的变量有 GOROOT、GOPATH 和 PATH。Go 1.10 以后,GOROOT 已经默认为 go 的当前安装路径,只要考虑 GOPATH 和 PATH 便可。session
最近,刚答过一个关于 Go 环境变量的问题,查看回答。其中对每一个变量的做用进行了比较细致的描述。curl
如今,我要实现我本身电脑上的两个版本的 Go 自由切换,该如何作呢?
假设它们分别位于 ~/.goversions/sdk/ 目录下的 go1.11/ 和 go1.13/。我如今要启用 go 1.11,运行以下命令便可:
$ export PATH=~/.goversions/sdk/go1.11/bin/:$PATH 复制代码
此时,GOROOT 已经自动识别,为 ~/.goversions/sdk/go1.11/。Go 相关的工具链,源码,标准库都在这个目录下。
但除 Go 自带外,还有其余第三方标准库、编译生成的库文件等内容,它们都位于 GOPATH 下,若是不设置,默认为 ~/go,在切换多版本的时候,就会产生混乱。咱们能够为每一个版本单独设置个 GOPATH。
如 go1.11,设置 GOPATH 为 ~/.goversions/gopath/go1.11-global/。
$ mkdir ~/.goversions/gopath/go1.11-global/ $ export GOPATH=~/.goversions/gopath/go1.11-global/ 复制代码
一个独立的环境建立好了。
若是如今要切换至 go 1.13,几个命令便可搞定。
$ export PATH=~/.goversions/sdk/go1.13/bin/:$PATH $ mkdir -pv ~/.goversions/gopath/go1.13-global/ $ export GOPATH=~/.goversions/gopath/go1.13-global/ 复制代码
切换成功。
虽然,已经实现了需求,但总以为用起来很是不爽。为了操做方便,其实能够把上面的思路提炼成 shell 脚本,整理成一套工具。
是否是蠢蠢欲动,想试一下?
但很遗憾,已经没这个机会了,由于这个工具已经有人开发了,思路相似,但却比这里描述的要强,它就是 gvm, 地址 moovweb/gvm。
gvm,即 Go Version Manager,Go 版本管理器,它能够很是轻量的切换 Go 版本。对比其余语言,一般也有相似的工具,如 NodeJS 的 NVM,Python 的 virtualenv 等。
gvm 不只包含上面提到的版本切换,还能够直接经过源码编辑安装任意版本的 Go,固然最好是 1.5 及以后版本,缘由后面解释。
一件比较尴尬的点,gvm 产生背景并不是是为了 Go 在不一样版本间的切换,开发团队当初开发这个工具主要为了解决项目的依赖问题,经过切换环境实现包依赖的切换。下面,我会演示如何作到这一点。
但问题是,如今 Go 的依赖管理已经日趋完善,官方的 go module 也愈来愈好用,GOPATH 在被逐渐弱化,gvm 彷佛也就只剩下帮咱们快速体验不一样 Go 版本的功能还有点价值。
废话说了那么多,开始正式体验下这个工具吧。
安装很简单,只要以下一行命令便可搞定。
$ bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer) 复制代码
输出显示:
Cloning from https://github.com/moovweb/gvm.git to /home/vagrant/.gvm which: no go in (/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/vagrant/.local/bin:/home/vagrant/bin) No existing Go versions detected Installed gvm v1.0.22 Please restart your terminal session or to get started right away run `source /home/vagrant/.gvm/scripts/gvm` 复制代码
安装完成!
重启控制台或执行 source $HOME/.gvm/scripts/gvm 便可启用 gvm。
提醒下,不一样操做系统还须要相应的依赖项要装,具体查看 项目说明 的介绍。 这里面没有提到 Windows,不知道可不可用。
gvm 经过从 github 下载源码编译 Go 的安装。而版本则是基于源码中的 tag。由于 1.5 版本及以后,Go 已经实现了自编译,于是要使用 gvm 安装 Go,咱们要提早有可用的 Go 环境。
Go 的安装能够阅读我以前的一篇文章 详细聊聊如何安装 Go,我认为介绍的还算详细。
Go 安装完成,就可使用 gvm 随意安装切换任意版本的 Go 了。
$ gvm install go1.11
复制代码
等待运行完成便可。
首次安装的时间可能会比较久,主要取决于你的网络,由于第一次须要从 github 下载源码。
首先,查看下个人系统已经安装的 Go 版本有哪些吧,相关命令 gvm list。
$ gvm list gvm gos (installed) go1.11 go1.12 go1.13 go1.13beta1 复制代码
安装了 4 个版本,其中,go1.13beta1 是非稳定版本,因此说,若是咱们想尽快尝试 go 的新特性,gvm 仍是很便捷的。
除了查看已安装的版本,还能够经过 gvm listall 查看全部版本,版原本源于源码中的 tag 标签。
$ gvm listall gvm gos (available) go1 go1.0.1 go1.0.2 go1.0.3 go1.1 ... go1.13 go1.13beta1 go1.13rc1 go1.13rc2 复制代码
但这个操做在 mac 上没法执行,gvm 的实现中用到了 Linux 的 sort 命令,它与 mac 上的 sort 不兼容。
怎么解决?
安装个软件 coreutils, 它之中有个 qsort 命令可用。经过 brew install coreutils 可直接安装。而后,修改下文件 $HOME/.gvm/scripts/function/tool,将其中的 sort 修改成 qsort 便可。
选择启用的版本就很是简单了。以下:
$ gvm use go1.11 [--default]
复制代码
启用成功后,能够经过 go version 和 go env 确认下。若是想默认一个版本,加上 --default 设置便可。
gvm 除了 Go 版本的管理,还能够管理包环境,相关命令是 pkgenv 和 pkgset。若是没使用包依赖管理工具,它也是挺方便的。
演示个例子,假设咱们要建立一个新的项目 blog,可提早建立相应的环境。
$ gvm pkgset create blog # 建立 $ gvm pkgset use blog # 启用 复制代码
如今,咱们经过 go get 安装的包都会默认在 blog 环境下。基于的原理是 go get 默认会把安装的放在 GOPATH 中的第一个目录下。
好了,就介绍这么多吧。有兴趣的朋友能够再研究研究。毕竟在有了 go mod 以后,这个功能之后是基本不会用了。
gvm 是 shell 编写,默认是安装在 $HOME/.gvm/ 目录下。查看下它的目录结构会有助咱们了解它的实现。
其中几个主要的目录,以下:
archive # go 源码 bin # gvm 可执行文件 environments # 不一样环境的环境变量配置 scripts # gvm 的子命令脚本 logs # 日志信息 pkgsets # 每一个独立环境 gopath 所在路径 复制代码
在研究了 gvm 的实现后,咱们会发现,这一套思路其实也适用于其余不少工具的版本管理。若是以后再遇到一样的需求,即便咱们没有现成的工具,本身实现一套也是能够的。
本文从个人需求出发,引出了如何灵活地进行管理 Go 版本的话题。
以往的经验告诉我,既然其余语言都有工具实现这样的需求,Go 也应该有。搜索了下,找到了 gvm。虽然说我在使用它的时候,发现了一些 bug 与体验很差的地方,但整体而言,已经足够知足个人需求。
Go 语言多版本安装及管理利器 - gvm
moovweb/gvm
gvm + go mod
欢迎关注个人公众号!