Go 使用 Workspace 实现本地扩展包
前言⌗
上一篇博客中讲到如何解决从 Gitlab 安装私有扩展包的方法,但是也发现了一系列的问题:
- 直接从 Gitlab Repository 拉去:这种方式最大的问题就是以来的包如果有代码改动,每次都要走一遍 Gitflow,比较麻烦!
- 使用
replace
将 Gitlab 上的包替换为本地的目录:这种方式虽然解决了上面的问题,但是也产生了新的额问题,就是当开发完成提交代码时,需要手动将 go.mod 文件中的 replace 的配置都删掉,如果项目只有一两个包还好,多了的话那可真是灾难。
Workspace 就是为了解决这一问题而残生的,它的优先级要高于 go.mod 所以如果在项目目录下创建了 go.work,那么只需要在 go.work 中配置 replace 就可以了。
初始化 Workspace⌗
在为项目初始化 Workspace 之前,我们可以看到现在 Go Env 中第 32 行的配置 GOWORK
是空的:
go env
GO111MODULE="on"
GOARCH="arm64"
GOBIN=""
GOCACHE="/Users/George/Library/Caches/go-build"
GOENV="/Users/George/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="arm64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/George/Develop/Go/pkg/mod"
GONOPROXY=""
GONOSUMDB="gitlab.example.com/services/modules"
GOOS="darwin"
GOPATH="/Users/George/Develop/Go"
GOPRIVATE=""
GOPROXY="direct"
GOROOT="/opt/homebrew/Cellar/go/1.19.2/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/opt/homebrew/Cellar/go/1.19.2/libexec/pkg/tool/darwin_arm64"
GOVCS=""
GOVERSION="go1.19.2"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/George/Develop/GA/udfs/server/go.mod"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/p6/g0wwf37d165dfg5hvqtr9l180000gn/T/go-build1666497732=/tmp/go-build -gno-record-gcc-switches -fno-common"
接下来执行初始化 Workspace 的命令:
go work init .
cat go.work
go 1.19
use .
会在项目目录中创建一个 go.work 的文件,这时候再查看 Go Env 会发现 GOWORK
的值变成了当前目录下的 go.work
:
GOWORK="/Users/George/Develop/udfs/server/go.work"
从本地安装依赖⌗
你可以可以在 use
中引入多个本地的包路径,这样在本地开发时,Go 会自动用 Workspace 下的包替换掉远端的包:
cat go.work
go 1.19
use (
.
../modules/inquiry
)
当然也可以在 go.work
中使用 replace
来替换掉 go.mod
中声明的依赖包为本地包路径:
go work edit -replace=gitlab.example.com/services/modules/inquiry=/Users/George/Develop/services/modules/inquiry
cat go.work
go 1.19
use .
replace gitlab.example.com/services/modules/inquiry => /Users/George/Develop/services/modules/inquiry
这样就在 go.work
文件中定义了一个 replace,从而使用本地的项目作为包的源。本地目录可以是相对或绝对路径,但是目录下必须要有 go.mod 文件。
另外需要将
go.work
和go.work.sum
文件加入.gitignore
配置文件中,否则会导致在 CI/CD 中无法找到对应的 package。
总结⌗
到这里在本地开发的问题就解决了,避免了每次修改需要走一遍包的发布流程。但是新的问题又来了,在执行 CI/CD 的流程中,如何按照环境来指定是从 Release Tag 安装还是从某个测试分支安装?
我将在后面的 CI/CD 实践中,继续探索这个问题,以及寻找最佳实践方案!
I hope this is helpful, Happy hacking…