前言

我自己在实际工作中经常遇到的问题就是:当需要新创建一个项目,常常需要手工做大量的事情,例如项目的配置、可观测性的集成以及一些基础设施的接入…

在创建新项目时,不同的负责人可能有不同的喜好难以标准化。即使是同一个人也难以保证其一致性,有过几次经历后,我们决定使用 Project template 来管理这些公共代码,避免重复性劳动。

但是在初始化项目时,我们还是通过 Git Clone 来实现新项目的创建,对比 laravel/installer 以及前端的项目脚手架,这虽然能解决问题,但显然不是最优解!

我发现 Go 官方发布了一篇 Experimenting with project templates 的 Blog,介绍的是一个实验性项目 golang.org/x/tools/cmd/gonew,通过它,我们可以使用模板快速创建一个项目。

其主要原理就是:下载一个 Module template,更改其 Module path,并将其放到本地的一个新目录中。

安装

go install golang.org/x/tools/cmd/gonew@latest

使用

gonew 命令语法如下:

gonew
usage: gonew srcmod[@version] [dstmod [dir]]
See https://pkg.go.dev/golang.org/x/tools/cmd/gonew.
  • srcmod: 源 Module path 的地址如 github.com/ServiceWeaver/template
  • @version: 下载指定版本的模板如 github.com/ServiceWeaver/template@v0.22.0,如果不指定则使用最新的
  • dstmod: 目标 Module path,如果不指定则使用源 Module path
  • dir: 保存到本地目录的名称

下面是具体用法示例:

# 下载最新版本
gonew github.com/ServiceWeaver/template

# 下载指定版本
gonew github.com/ServiceWeaver/template@v0.22.0

# 将指定的模板下载后并替换 Go module path 为 gitlab.test/services/backend
gonew github.com/ServiceWeaver/template gitlab.test/services/backend

# 将指定的模板下载后并替换 Go module path 为 gitlab.test/services/backend,并指定本地目录名称
gonew github.com/ServiceWeaver/template gitlab.test/services/backend backend

Gitlab 私有项目

我们是使用 Self-hosted 的 Gitlab 来作为代码管理系统的,项目模板跟私有 Module 是类似的。

gonew gitlab.test/services/sendbox
gonew: go mod download -json gitlab.test/services/sendbox@latest: exit status 1
{
	"Path": "gitlab.test/services/sendbox",
	"Version": "v1.3.0",
	"Query": "latest",
	"Error": "gitlab.test/services/sendbox@v1.3.0: verifying go.mod: gitlab.test/services/sendbox@v1.3.0/go.mod: Get \"https://proxy.golang.org/sumdb/sum.golang.org/supported\": dial tcp 142.251.42.241:443: i/o timeout",
	"Info": "/Users/George/Develop/Go/pkg/mod/cache/download/gitlab.test/services/sendbox/@v/v1.3.0.info",
	"Origin": {
		"VCS": "git",
		"URL": "https://gitlab.test/services/sendbox.git",
		"TagSum": "t1:8u5g92aMnUe25PzyvfLHGI+FiAP55e2BtcL+03OfxwA=",
		"Ref": "refs/tags/v1.3.0",
		"Hash": "9f6d23e699a844087d2d429a45379245b91e86d4"
	}
}

如果遇到上面的问题,则需要将 Gitlab 域名加入到 GONOSUMDB 环境变量中,避免再去做校验!

go env -w GONOSUMDB="gitlab.test"
gonew gitlab.test/services/sendbox
gonew: initialized gitlab.test/services/sendbox in ./sendbox

总结

gonew 出现以前,也有很多框架开发了自己的脚手架,但大多是针对性的,而 gonew 问世后,简化了这一工作,让我们只需关注业务即可。

对于一些 CI/CD 的配置,如 Dockerfiledocker-compose.yaml 等都可以在 Project template 中进行进行统一管理,通过这种约定大于配置的协作模式,极大的降低了团队成员之间的沟通成本!

I hope this is helpful, Happy hacking…