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

本文谈下我对 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.22Please 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 listgvm gos (installed)go1.11go1.12go1.13go1.13beta1

安装了 4 个版本,其中,go1.13beta1 是非稳定版本,所以说,如果我们想尽快尝试 go 的新特性,gvm 还是很便捷的。

除了查看已安装的版本,还可以通过 gvm listall 查看所有版本,版本来源于源码中的 tag 标签。

$ gvm listallgvm gos (available)go1go1.0.1go1.0.2go1.0.3go1.1...go1.13go1.13beta1go1.13rc1go1.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.mzph.cn/news/643305.shtml

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

相关文章

探索未来:2024 年 5 大前沿生成式 AI 趋势

探索未来&#xff1a;2024 年 5 大前沿生成式 AI 趋势 1. 多模态 AI 模型的崛起2. 功能强大且强大的小型语言模型3. 自主代理的崛起4. 开源模型将与专有模型匹敌5. 云原生成为本地 GenAI 的关键总结 2023 年标志着技术发展的一个分水岭&#xff0c;生成式 AI 走入了主流。随着 …

牛客:X图形

描述 KiKi学习了循环&#xff0c;BoBo老师给他出了一系列打印图案的练习&#xff0c;该任务是打印用“*”组成的X形图案。 输入描述&#xff1a; 多组输入&#xff0c;一个整数&#xff08;2~20&#xff09;&#xff0c;表示输出的行数&#xff0c;也表示组成“X”的反斜线和…

浙政钉-H5小程序应用采集开发手册

浙政钉-H5&小程序应用采集开发手册 埋点代码分为:稳定性监控代码(Emas)和流量分析代码(A+)。稳定性监控代码(Emas)只需要在首页加入。流量分析代码(A+)每个页面都需要加入,但是可以写通用js,在其他页面引入。 适用范围 本文档适用于浙政钉业务web(H5)或小程序应…

GPT只是开始,Autonomous Agents即将到来

生成式AI虽然很早便已经引起了广泛关注&#xff0c;但直到ChatGPT的出现&#xff0c;许多公司的领导层才切身感受到了大语言模型&#xff08;LLM&#xff09;带来的深远影响。面临这种行业变革&#xff0c;诸多企业正争先恐后地加入到这场潮流中&#xff0c;但生成式AI的进步速…

【力扣 445】两数相加 II C++题解(链表+模拟+数学+头插法)

给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数字都不会以零开头。 示例1&#xff1a; 输入&#xff1a;l1 [7,2,4,3], l2 [5,6,4]…

indexedDB的基本操作

indexedDB概述 IndexedDB 就是浏览器提供的本地数据库&#xff0c;它可以被网页脚本创建和操作。IndexedDB 允许储存大量数据&#xff0c;提供查找接口&#xff0c;还能建立索引。这些都是 LocalStorage 所不具备的。就数据库类型而言&#xff0c;IndexedDB 不属于关系型数据库…

算法训练营Day55(子序列--编辑距离)

392.判断子序列 392. 判断子序列 - 力扣&#xff08;LeetCode&#xff09; 这道题目算是 编辑距离问题 的入门题目&#xff08;毕竟这里只是涉及到减法&#xff09;&#xff0c;慢慢的&#xff0c;后面就要来解决真正的编辑距离问题了 和最长公共子序列相似 他那道题区别就是e…

期待已久!阿里云容器服务 ACK AI 助手正式上线

作者&#xff1a;行疾 大模型技术的蓬勃发展持续引领 AI 出圈潮流&#xff0c;各行各业都在尝试采用 AI 工具实现智能增效。 2023 年云栖大会上&#xff0c;阿里云容器服务团队正式发布 ACK AI 助手&#xff0c;带来大模型增强智能诊断&#xff0c;帮助企业和开发者降低 K8s …

Spark运行架构以及容错机制

Spark运行架构以及容错机制 1. Spark的角色区分1.1 Driver1.2 Excuter 2. Spark-Cluster模式的任务提交流程2.1 Spark On Yarn的任务提交流程2.1.1 yarn相关概念2.1.2 任务提交流程 2.2 Spark On K8S的任务提交流程2.2.1 k8s相关概念2.2.2 任务提交流程 3. Spark-Cluster模式的…

BACnet网关BA100实现Modbus转BACnet,专为Modbus协议设备与BA系统的高效对接设计

随着物联网技术的迅猛发展&#xff0c;人们深刻认识到在智能化生产和生活中&#xff0c;实时、可靠、安全的数据传输至关重要。在此背景下&#xff0c;高性能的物联网数据传输解决方案——协议转换网关应运而生&#xff0c;广泛应用于工业自动化和数字化工厂应用环境中。 钡铼…

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

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

深度学习-循环神经网络-RNN实现股价预测-LSTM自动生成文本

序列模型(Sequence Model) 基于文本内容及其前后信息进行预测 基于目标不同时刻状态进行预测 基于数据历史信息进行预测 序列模型:输入或者输出中包含有序列数据的模型 突出数据的前后序列关系 两大特点: 输入(输出)元素之间是具有顺序关系。不同的顺序,得到的结果应…

安全基础~通用漏洞1

文章目录 知识补充Acess数据库注入MySQL数据库PostgreSQL-高权限读写注入MSSQL-sa高权限读写执行注入Oracle 注入Mongodb 注入sqlmap基础命令 知识补充 order by的意义&#xff1a; union 操作符用于合并两个或多个 select语句的结果集。 union 内部的每个 select 语句必须拥有…

哈希--73. 矩阵置零/medium 理解度A

73. 矩阵置零 1、题目2、题目分析3、复杂度最优解代码示例4、适用场景 1、题目 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,…

express 项目支持 typescript 实战

首先创建一个express项目 初始化项目 mkdir myapp cd myapp npm init (都用默认值)添加依赖包 npm install express nodemon修改 package.json {"name": "myapp","version": "1.0.0","description": "","…

$.ajax与同源策略

1.jQuery中的ajax请求 学习Jquery中的ajax,我们借助官方文档 $.ajax(url,[settings]) | jQuery API 3.2 中文文档 | jQuery API 在线手册 使用$.ajax()方法完成图书案例 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8&quo…

Oracle dbms_sql 的用法

DBMS_SQL 是 Oracle 数据库中的一个包&#xff0c;用于动态执行 SQL 语句。它允许您在运行时构建和执行 SQL 语句&#xff0c;提供了对动态 SQL 的支持。以下是 DBMS_SQL 的基本用法&#xff1a; 打开游标: 使用 DBMS_SQL.OPEN_CURSOR 打开一个游标。 DECLARE l_cur INTEGER;…

mc我的世界服务器多少钱一个月?

我的世界服务器多少钱一个月&#xff1f;低至7元一个月&#xff0c;阿里云和腾讯云均可以选择mc服务器&#xff0c;阿里云2核2G3M轻量服务器87元一年、腾讯云轻量2核2G3M服务器88元一年&#xff0c;阿里云ECS云服务器2核2G3M带宽99元一年&#xff0c;腾讯云2核4G5M带宽轻量应用…

RabbitMQ中交换机的应用 ,原理 ,案例的实现

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是平顶山大师&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《RabbitMQ中交换机的应用及原理&#xff0c;案…

8.Gateway服务网关

3.Gateway服务网关 Spring Cloud Gateway 是 Spring Cloud 的一个全新项目&#xff0c;该项目是基于 Spring 5.0&#xff0c;Spring Boot 2.0 和 Project Reactor 等响应式编程和事件流技术开发的网关&#xff0c;它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式…