golang多版本管理

在我们的开发环境中,使多个golang版本并存。

大部分情况下,一个比较新的golang版本就能满足我们的日常的开发需求。

但是项目中,因为协作的原因,或者由于项目启动比较早,可能我们不同的工程需要用不同的golang版本。甚至有些工作用比较新的版本编译不了。

这时候,我们就需要让本地的开发环境支持多个golang版本。

官方解决方案

当前,golang提供了一个官方的解决方案,我们只要go install对应的go版本,然后就能使用特定的版本进行工作了。

官方repo:golang.org/dl

使用方式也比较简单,比如我们要安装一个1.18的版本,只需要两步

  1. go install golang.org/dl/go1.18@latest
  2. go1.18 download

之后只需要用go1.18替换go命令,即可使用特定的这个版本进行go相关的工作了。

但是go1.18go多了好几个字符,而且由于肌肉记忆,可能我们敲了go之后就会敲后面的内容了。为了让go直接当成特定的版本使用,我们可以设置环境变量, 设置好GOROOT和把特定版本的go放到PATH前面即可。

如下,我们把下面的内容设置到我们的shell加载配置里。

bash 复制代码
export GOROOT=$(go1.18 env GOROOT)
export PATH=$GOROOT/bin:$PATH

如果是bash,放在~/.bashrc里,如果是zsh,则放在~/.zshrc里,如果是fish则放在~/.config/fish/config.fish

到此,我们就可以使用特定版本的golang了,一个开发环境也安装了多个版本的golang。

不同工程自动加载特定的版本

以上在shell配置中配置特定版本,在不同的工程中就行不通了。因为配置文件是全局的。如果用特定的版本号来运行,我们除了要敲多版本号外,还需要记得每个工作用的是哪一个版本的go。

有没有办法在我们cd到特定的目录时,自动配置环境变量,离开的时候,自动释放这些环境变量呢?

direnv可以帮我们完成这一项工作。它可以在特定目录上,把环境变量写到.envrc,那cd进去就会自动加载,离开就会自动释放。

使用自己操作系统的包管理安装好direnv后,接下来cd到我们特定的工程,假如这个工程使用1.18的版本,我们只要把下面这一段配置放到.envrc即可。

bash 复制代码
export GOROOT=$(go1.18 env GOROOT)
export PATH=$GOROOT/bin:$PATH

配置好后,direnv会提示需要对这个目录进行授权,执行以下命令即可

bash 复制代码
direnv allow

这样我们就可以安装好多个golang版本,然后在不同的工程中配置好.envrc,就能在特定的工程用特定的版本go了。

direnv使用的是bash的方案配置环境变量,所以在fish这种非标准POSIX shell,也需要使用以上的语法进行配置。

gg管理golang版本

基于官方的解决方案,我们解决了多个版本的并存问题和运行问题。但是,我们本地安装了哪些版本,官方发布了哪些版本可以给我们用?

gg这个工具为我们提供了非常方便的管理方式。它支持以下能力

  • 查看本地版本列表
  • 官方的所有版本列表
  • 安装官方版本到本地
  • 删除版本
  • 打印特定版本的环境变量

它直接基于官方的解决方案做了包装,把安装的两步合成了一个步,打印环境变量配置。

目前gg只支持fish shell

gg ls 查看本地版本

golang.org/dl的安装,会把go的数据下载到~/sdk目录下。gg ls命令会去查看这个目录存在哪些版本,进行打印。

gg ls-remote 查看官方版本

gg ls-remote会去爬出官方的版本进行展示,同时会把结果缓存起来。缓存有效期24小时。使用缓存后,可以避免每次去爬取,加快运行速度。

gg install 安装特定的版本

比如上面我们介绍的安装1.18版本,我们只需要运行下面的命令

bash 复制代码
gg install 1.18

它会使用全局的go版本,去完成安装的两步

  1. go install golang.org/dl/go1.18@latest
  2. go1.18 download

gg remove删除特定版本

删除特定的版本,只需要把$GOPATH/bin下特定的版本删除,把~/sdk下特定版本删除即可。所以gg remove的工作比较简单。

bash 复制代码
gg remove 1.18

gg use使用特定的版本

这个命令会把特定版本需要的环境变量打印出来,可以直接进行source或者重定向到.envrc上。 比如对于bash的环境变量

bash 复制代码
gg use --bash 1.18

它会输出以下的内容

bash 复制代码
# source this code to enable it
# for example:
# > gg use --bash 1.18 | source

# if you use direnv to manage environment, you can redirect the output to .envrc in the current directory
# > gg use --bash 1.18 >> .envrc; direnv allow

export GOROOT=$(go1.18 env GOROOT)
export PATH=$GOROOT/bin:$PATH

或者fish的环境变量

bash 复制代码
gg use --fish 1.18

它会输出以下的内容

bash 复制代码
# source this code to enable it
# for example:
# > gg use --fish 1.18 | source

set -gx GOROOT (go1.18 env GOROOT)
fish_add_path $GOROOT/bin

如果不指定特定的shell,它会指定为当前的登录shell。

如果要使用direnv,则需要指定为bash

总结

基于以上,只需要使用gg即可完成官方方案的多版本解决版本。再加上direnv即可让我们在特定的工程自动使用特定的版本。

相关推荐
Grassto1 天前
12 go.sum 是如何保证依赖安全的?校验机制源码解析
安全·golang·go·哈希算法·go module
Grassto3 天前
11 Go Module 缓存机制详解
开发语言·缓存·golang·go·go module
程序设计实验室4 天前
2025年的最后一天,分享我使用go语言开发的电子书转换工具网站
go
我的golang之路果然有问题4 天前
使用 Hugo + GitHub Pages + PaperMod 主题 + Obsidian 搭建开发博客
golang·go·github·博客·个人开发·个人博客·hugo
啊汉6 天前
古文观芷App搜索方案深度解析:打造极致性能的古文搜索引擎
go·软件随想
asaotomo6 天前
一款 AI 驱动的新一代安全运维代理 —— DeepSentry(深哨)
运维·人工智能·安全·ai·go
码界奇点7 天前
基于Gin与GORM的若依后台管理系统设计与实现
论文阅读·go·毕业设计·gin·源代码管理
迷迭香与樱花7 天前
Gin 框架
go·gin
只是懒得想了7 天前
用Go通道实现并发安全队列:从基础到最佳实践
开发语言·数据库·golang·go·并发安全
fenglllle8 天前
使用fyne做一个桌面ipv4网段计算程序
开发语言·go