Go 虚拟环境管理工具 gvm 原理介绍与使用指南

news2024/12/26 14:23:08

本文谈下我对 Go 版本管理的一些想法。让后,我将介绍一个小工具,gvm。这个话题说起来也很简单,但如果想用的爽,还是要稍微梳理下。

背景介绍

Go 的版本管理,并非包的依赖管理,而且关于如何在不同的 Go 版本之间切换。平时的工作中,正常情况,我们不会遇到这样的需求,所以可能并不明白它的价值。

简单说下我写这篇文章的背景吧。

最近几周,Go 最重要的一则消息应该莫过 9月份 Go 1.13 的正式发布。它的相关升级可查看 Go 1.13 正式发布,看看都有哪些值得关注的特性 或官方 Go 1.13 Relase Notes。

对于一名 gopher 而言,可能早已按捺不住自己那颗躁动的心,想尽快体验下新版的升级项。但问题是,切换至新版 Go 通常会遇到一些问题,比如不同版本的环境配置,安装的辅助工具和程序包在不同版本下可能会存在兼容或被覆盖等问题。

我自然就希望有一套方案可以帮助我完成 Go 版本的切换,实现不同版本间环境的完全隔离。

思考方案

谈到环境隔离,有很多方案可供选择,如多主机、虚拟机、容器等技术。这些听起来都挺不错,都能实现需求。但如果只是为了 Go 版本管理,完全可以自己实现。

多版本切换,主要是不同版本环境变量的隔离。Go 1.10 之前,我们关心的变量有 GOROOT、GOPATH 和 PATH。Go 1.10 之后,GOROOT 已经默认为 go 的当前安装路径,只要考虑 GOPATH 和 PATH 即可。

最近,刚答过一个关于 Go 环境变量的问题,查看回答。其中对每个变量的作用进行了比较细致的描述。

如何实现

现在,我要实现我自己电脑上的两个版本的 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

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 安装 Go

gvm 通过从 github 下载源码编译 Go 的安装。而版本则是基于源码中的 tag。因为 1.5 版本及之后,Go 已经实现了自编译,因而要使用 gvm 安装 Go,我们要提前有可用的 Go 环境。

好在,gvm 也提供直接通过下载二进制包的方式安装 Go。

❯ gvm install go1.19 --binary
Installing go1.19 from binary source

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 目录结构

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

博文地址:Go 虚拟环境管理工具 gvm

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1408005.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

配置dns主从服务器,实现正反向解析

一、安装bind服务 yum install bind -y二、修改主配置文件/etc/named.conf 三、配置数据配置文件/var/named/baidu 四、重启服务&#xff0c;进行测试 systemctl restart named

【进口控制器替代】基于Zynq-7020 FPGA的NI 8槽CompactRIO控制器

667 MHz双核CPU&#xff0c;512 MB DRAM&#xff0c;1 GB存储容量&#xff0c;Zynq-7020 FPGA&#xff0c;更宽工作温度范围&#xff0c;8槽CompactRIO控制器 cRIO-9068是一款坚固耐用的无风扇嵌入式控制器&#xff0c;可用于高级控制和监测应用。这款软件设计控制器搭载FPGA、…

链表的反转方法1--迭代法

// 链表头指针结构 typedef struct header {int length; //存储链表结点个数struct linklist *next;//指针域 } Header;// 链表结点结构 typedef struct linknode {int data;//数据域struct linknode* next;//指针域 } LinkNode; 迭代法1-初级版&#xff1a; //反转链表方式1 …

Web06--JavaScript基础02

1、JS流程控制语句 JS与Java一样&#xff0c;也有三个流程控制语句&#xff1a; 顺序结构 选择结构 循环结构 1.1 选择结构 1.1.1 if结构 <script type"text/javascript">if (条件表达式) {代码块;} else if(条件表达式){代码块;} else {代码块;} </scr…

Nas-FPN(CVPR 2019)原理与代码解析

paper&#xff1a;NAS-FPN: Learning Scalable Feature Pyramid Architecture for Object Detection third-party implementation&#xff1a;https://github.com/open-mmlab/mmdetection/tree/main/configs/nas_fpn 本文的创新点 本文采用神经网络结构搜索&#xff08;Neur…

bash 5.2中文修订4

Compound Commands 复合命令 复合命令是 shell 编程语言的结构。每个构造都以保留字或控制运算符开始&#xff0c;并以相应的保留字或运算符终止。与复合命令关联的任何重定向&#xff08;请参阅 Redirections &#xff09;都适用于该复合命令中的所有命令&#xff0c;除非显式…

高质量简历模板网站,免费、免费、免费

你们在制作简历时&#xff0c;是不是基本只关注两件事&#xff1a;简历模板&#xff0c;还有基本信息的填写。 当你再次坐下来更新你的简历时&#xff0c;可能会发现自己不自觉地选择了那个“看起来最好看的模板”&#xff0c;填写基本信息&#xff0c;却没有深入思考如何使简历…

搜维尔科技:【简报】元宇宙数字人赛道,《莉思菱娜》

个性有些古灵精怪时儿安静时而吵闹&#xff0c;虽然以人类寿命来算已经200多岁但在 吸血鬼中还只是个小毛头&#xff0c;从中学开始喜欢打扮偏爱黑白灰色系的服装喜欢时 尚圈&#xff0c;立志想成为美妆或时尚网红不过目前还是学生&#xff0c;脸上的浅色血迹是纹身 贴纸&#…

Spark读取kafka(流式和批数据)

spark读取kafka&#xff08;批数据处理&#xff09; # 按照偏移量读取kafka数据 from pyspark.sql import SparkSessionss SparkSession.builder.getOrCreate()# spark读取kafka options {# 写kafka配置信息# 指定kafka的连接的broker服务节点信息kafka.bootstrap.servers: n…

《幻兽帕鲁》被指AI缝合,开发过程疑点重重,最后附游戏安装教程

由日本游戏工作室Pocketpair开发的《Palworld / 幻兽帕鲁》毫无疑问成为了2024年的首个巨热游戏&#xff01;上周五&#xff08;2024年1月19日&#xff09;游戏上线抢先体验&#xff0c;仅在3天内销量就已突破400万&#xff01;并于2024年1月21日创下了1291967名同时在线玩家的…

[ACM学习] 树形dp之换根

算法概述 总的来说&#xff1a; 题目描述&#xff1a;一棵树求哪一个节点为根时&#xff0c;XXX最大或最小 分为两步&#xff1a;1. 树形dp 2. 第二次dfs 问题引入 如果暴力就是 O(n^2) &#xff0c; 当从1到2的时候&#xff0c;2及其子树所有的深度都减一&#xff0c;其它…

手把手教你快速掌握连接远程git仓库or赋值远程仓库到本地并上传代码到gitee

1. 先去官网安装Git &#xff0c;这里不多赘述网上教程很多 2.1去gitee注册一个账号&#xff0c;然后去我的新建一个仓库&#xff0c;这里是演示一下新手第一次操作的流程 2.2设置仓库名称完成创建(这里的库名随便输入看自己)&#xff1a; 2.3 打开git bash 配置用户名&#x…

Kubernetes-Taint (污点)和 Toleration(容忍)

目录 一、Taint&#xff08;污点&#xff09; 1.污点的组成 2.污点的设置、查看和去除 3.污点实验&#xff1a; 二、Toleration&#xff08;容忍&#xff09; 1.容忍设置的方案 2.容忍实验&#xff1a; Taint 和 toleration 相互配合&#xff0c;可以用来避免 pod 被分配…

VUE3好看的我的家乡网站模板源码

文章目录 1.设计来源1.1 首页界面1.2 旅游导航界面1.3 上海景点界面1.4 上海美食界面1.5 上海故事界面1.6 联系我们界面1.7 在线留言界面 2.效果和结构2.1 动态效果2.2 代码结构 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/…

虹科方案丨湿热灭菌工艺验证解决方案,确保所有产品和容器达到无菌要求

来源&#xff1a;虹科环境监测技术 虹科方案丨湿热灭菌工艺验证解决方案&#xff0c;确保所有产品和容器达到无菌要求 原文链接&#xff1a;https://mp.weixin.qq.com/s/O-pKQdehB9mHSETpU8egbA 欢迎关注虹科&#xff0c;为您提供最新资讯&#xff01; #蒸汽灭菌 #高压灭菌 …

小程序直播系统源码_报价与开发_OctShop

近几年&#xff0c;随着直播的火热&#xff0c;人们对于直播带货是相当的熟悉了&#xff0c;逐渐渗透到各行各业中&#xff0c;小程序直播可以实时的更全面的传递商品信息&#xff0c;同时还可以与主播进行互动&#xff0c;可以通过直播聚集的人气打造团购气氛&#xff0c;通过…

LSTM时间序列预测

本文借鉴了数学建模清风老师的课件与思路&#xff0c;可以点击查看链接查看清风老师视频讲解&#xff1a;【1】演示&#xff1a;基于LSTM深度学习网络预测时间序列&#xff08;MATLAB工具箱&#xff09;_哔哩哔哩_bilibili % Forecast of time series based on LSTM deep learn…

win 下使用 cmd 运行 jar 包

1、使用 Win R 输入 cmd 命令打开命令提示符 2、在 cmd 窗口中输入以下命令 java -jar xxxxxx.jar 运行 jar 包&#xff0c;控制台出现中文乱码 原因是 windows 默认使用 GBK 编码格式&#xff0c;程序使用 UTF-8 编码格式 将编码格式改为 UTF-8 编码&#xff0c;在 cmd 窗…

C#中IsNullOrEmpty和IsNullOrWhiteSpace的区别?

前言 今天我们一起来探讨C#中两个常用的字符串处理方法&#xff1a;IsNullOrEmpty和IsNullOrWhiteSpace。这两个方法在处理字符串时非常常见&#xff0c;但是它们之间存在一些细微的区别。在本文中&#xff0c;我们将详细解释这两个方法的功能和使用场景&#xff0c;并帮助您更…

Qt Quick程序的发布|Qt5中QML和Qt Quick 的更改

# Quick程序的发布旧版做法 # Qt5中QML和Qt Quick 的更改 1.QML语言的更改(Qt4->Qt5) 在QML语言中,只有少量更改会影响QML代码的迁移:无法直接导入单独的文件(例如:import"MyType.qml”),需要导人该文件所在的目录; JavaScript文件中的相对路径被解析…