Go 版本管理器 (GVM) 是一个用于管理 Go 环境的开源工具。它支持安装多个 Go 版本,并使用 GVM “pkgsets” 管理每个项目的模块。GVM 最初由 Josh Bussdieker 开发(类似于其 Ruby 对应物 RVM),允许您为每个项目或项目组创建开发环境,隔离不同的 Go 版本和包依赖项,从而实现更大的灵活性并防止版本控制问题。
有几种管理 Go 包的选项,包括 Go 1.11 模块,它内置于 Go 中。我发现 GVM 简单直观,即使我不使用它来管理包,我仍然会使用它来管理 Go 版本。
安装 GVM
安装 GVM 很简单。GVM 仓库安装文档指示您下载安装脚本并将其管道传输到 Bash
bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
尽管这种安装方法的采用率越来越高,但最好还是先查看安装程序在做什么,然后再执行它。对于 GVM,安装脚本
- 检查一些依赖项
- 克隆 GVM 仓库
- 使用 shell 脚本来
- 安装 Go
- 管理 GOPATH 环境
- 在您的 bashrc、zshrc 或 profile 中添加一行
如果您想仔细检查它在做什么,您可以克隆仓库并查看 shell 脚本,然后运行 ./binscripts/gvm-installer 以使用本地脚本进行设置。
注意: 由于 GVM 可用于下载和编译新的 Go 版本,因此需要一些预期的依赖项,如 Make、Git 和 Curl。您可以在 GVM 的 README 中找到适合您发行版的完整列表。
使用 GVM 安装和管理 Go 版本
安装 GVM 后,您可以开始使用它来安装和管理不同版本的 Go。gvm listall 命令显示可以下载和编译的可用 Go 版本
[chris@marvin ]$ gvm listall
$ gvm listall
gvm gos (available)
go1
go1.0.1
go1.0.2
go1.0.3
<output truncated>
安装特定的 Go 版本就像 gvm install <version> 一样简单,其中 <version> 是 gvm listall 命令返回的版本之一。
假设您正在处理一个使用 Go 版本 1.12.8 的项目。您可以使用 gvm install go1.12.8 安装它
[chris@marvin]$ gvm install go1.12.8
Installing go1.12.8...
* Compiling...
go1.12.8 successfully installed!
输入 gvm list,您会看到 Go 版本 1.12.8 已安装以及系统 Go 版本(使用您的操作系统软件包管理器打包的版本)
[chris@marvin]$ gvm list
gvm gos (installed)
go1.12.8
=> 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 模块(在 Go v1.11 中添加了初步支持)和 go dep(“官方实验”和 Go 模块的持续替代方案)。在我发现 GVM 之前,我会在自己的 Docker 容器中构建和测试 Go 项目,以确保隔离。
GVM 通过使用 “pkgsets” 将项目的新目录附加到已安装 Go 版本的默认 $GOPATH,从而优雅地实现了项目之间包的管理和隔离,这很像 $PATH 在 Unix/Linux 系统上的工作方式。
最容易通过实际操作来可视化它的工作原理。首先,安装一个新版本的 Go,v1.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,该 $GOPATH 对应于该版本的默认 global 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 创建一个新的名为 introToGvm 的 pkgset
[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}' <<< $GOPATH )
[chris@marvin]$ pwd
/home/chris/.gvm/pkgsets/go1.12.9/introToGvm
[chris@marvin]$ ls
overlay pkg src
请注意,新目录看起来很像正常的 $GOPATH。可以使用通常与 Go 一起使用的相同 go get 命令下载新的 Go 包,并将它们添加到 pkgset。
例如,使用以下命令获取 gorilla/mux 包,然后检查 pkgset 的目录结构
[chris@marvin]$ go get github.com/gorilla/mux
[chris@marvin]$ tree
[chris@marvin introToGvm ]$ tree
.
├── overlay
│ ├── bin
│ └── lib
│ └── pkgconfig
├── pkg
│ └── linux_amd64
│ └── github.com
│ └── gorilla
│ └── mux.a
src/
└── github.com
└── gorilla
└── mux
├── AUTHORS
├── bench_test.go
├── context.go
├── context_test.go
├── doc.go
├── example_authentication_middleware_test.go
├── example_cors_method_middleware_test.go
├── example_route_test.go
├── go.mod
├── LICENSE
├── middleware.go
├── middleware_test.go
├── mux.go
├── mux_test.go
├── old_test.go
├── README.md
├── regexp.go
├── route.go
└── test_helpers.go
您可以看到,gorilla/mux 已按预期添加到 pkgset $GOPATH 目录中,现在可以与使用此 pkgset 的项目一起使用。
GVM 使 Go 管理变得轻而易举
GVM 是一种直观且非侵入性的方式来管理 Go 版本和包。它可以单独使用,也可以与其他 Go 模块管理技术结合使用,并利用 GVM 的 Go 版本管理功能。通过 Go 版本和包依赖项隔离项目,可以使开发更容易,并减少管理版本冲突的复杂性,而 GVM 使这一切变得轻而易举。
1 条评论