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即可让我们在特定的工程自动使用特定的版本。

相关推荐
郝同学的测开笔记4 小时前
云原生探索系列(十二):Go 语言接口详解
后端·云原生·go
一点一木21 小时前
WebAssembly:Go 如何优化前端性能
前端·go·webassembly
千羽的编程时光1 天前
【CloudWeGo】字节跳动 Golang 微服务框架 Hertz 集成 Gorm-Gen 实战
go
27669582923 天前
阿里1688 阿里滑块 231滑块 x5sec分析
java·python·go·验证码·1688·阿里滑块·231滑块
Moment4 天前
在 NodeJs 中如何通过子进程与 Golang 进行 IPC 通信 🙄🙄🙄
前端·后端·go
唐僧洗头爱飘柔95274 天前
(Go基础)变量与常量?字面量与变量的较量!
开发语言·后端·golang·go·go语言初上手
黑心萝卜三条杠4 天前
【Go语言】深入理解Go语言:并发、内存管理和垃圾回收
google·程序员·go
不喝水的鱼儿5 天前
【LuatOS】基于WebSocket的同步请求框架
网络·websocket·网络协议·go·luatos·lua5.4
微刻时光5 天前
程序员开发速查表
java·开发语言·python·docker·go·php·编程语言
lidenger5 天前
服务认证-来者何人
后端·go