如何用 GVM 管理 Go 项目
使用 Go 版本管理器管理多个版本的 Go 语言环境及其模块。
Go 语言版本管理器(GVM)是管理 Go 语言环境的开源工具。GVM “pkgsets” 支持安装多个版本的 Go 并管理每个项目的模块。它最初由 Josh Bussdieker 开发,GVM(像它的对手 Ruby RVM 一样)允许你为每个项目或一组项目创建一个开发环境,分离不同的 Go 版本和包依赖关系,以提供更大的灵活性,防止不同版本造成的问题。
有几种管理 Go 包的方式,包括内置于 Go 中的 Go 1.11 的 Modules。我发现 GVM 简单直观,即使我不用它来管理包,我还是会用它来管理 Go 不同的版本的。
安装 GVM
安装 GVM 很简单。GVM 存储库安装文档指示你下载安装程序脚本并将其传送到 Bash 来安装:
bash < system
GVM 仍在使用系统版本的 Go ,由 =>
符号表示。你可以使用 gvm use
命令切换你的环境以使用新安装的 go1.12.8:
[chris@marvin]$ gvm use go1.12.8
Now using version go1.12.8
[chris@marvin]$ go version
go version go1.12.8 linux/amd64
GVM 使管理已安装版本的 Go 变得极其简单,但它不止于此!
使用 GVM pkgset
开箱即用,Go 有一种出色而令人沮丧的管理包和模块的方式。默认情况下,如果你 go get
获取一个包,它将被下载到 $GOPATH
目录中的 src
和 pkg
目录下,然后可以使用 import
将其包含在你的 Go 程序中。这使得获得软件包变得很容易,特别是对于非特权用户,而不需要 sudo
或 root 特权(很像 Python 中的 pip install --user
)。然而,在不同的项目中管理相同包的不同版本是非常困难的。
有许多方法可以尝试修复或缓解这个问题,包括实验性 Go Modules(Go 1.11 版中增加了初步支持)和 Go dep(Go Modules 的“官方实验”并且持续迭代)。在我发现 GVM 之前,我会在一个 Go 项目自己的 Docker 容器中构建和测试它,以确保分离。
GVM 通过使用 “pkgsets” 将项目的新目录附加到安装的 Go 版本的默认 $GOPATH
上,很好地实现了项目之间包的管理和隔离,就像 $PATH
在 Unix/Linux 系统上工作一样。
想象它如何运行的。首先,安装新版 Go 1.12.9:
[chris@marvin]$ echo $GOPATH
/home/chris/.gvm/pkgsets/go1.12.8/global
[chris@marvin]$ gvm install go1.12.9
Installing go1.12.9...
* Compiling...
go1.12.9 successfully installed
[chris@marvin]$ gvm use go1.12.9
Now using version go1.12.9
当 GVM 被告知使用新版本时,它会更改为新的 $GOPATH
,默认 gloabl
pkgset 应用于该版本:
[chris@marvin]$ echo $GOPATH
/home/chris/.gvm/pkgsets/go1.12.9/global
[chris@marvin]$ gvm pkgset list
gvm go package sets (go1.12.9)
=> global
尽管默认情况下没有安装额外的包,但是全局 pkgset 中的包对于使用该特定版本的 Go 的任何项目都是可用的。
现在,假设你正在启用一个新项目,它需要一个特定的包。首先,使用 GVM 创建一个新的 pkgset,名为 introToGvm
:
[chris@marvin]$ gvm pkgset create introToGvm
[chris@marvin]$ gvm pkgset use introToGvm
Now using version go1.12.9@introToGvm
[chris@marvin]$ gvm pkgset list
gvm go package sets (go1.12.9)
global
=> introToGvm
如上所述,pkgset 的一个新目录被添加到 $GOPATH
:
[chris@marvin]$ echo $GOPATH
/home/chris/.gvm/pkgsets/go1.12.9/introToGvm:/home/chris/.gvm/pkgsets/go1.12.9/global
将目录更改为预先设置的 introToGvm
路径,检查目录结构,这里使用 awk
和 bash
完成。
[chris@marvin]$ cd $( awk -F':' '{print $1}'