Goreleaser 和 TraivsCI 这边就不再过多介绍,可以去它们官网上了解。这边主要是介绍 gopo
以及如何把它发布出去供人使用。那这篇文章也相应的分为两个部分。
gopo
gopo
说白了就是解析 go 中的结构体,生成对应的结构体字段常量表。也就是说:
type SomeTable struct{
Id int `gorm:"primary_key" json:"id"` //记录id
Height float32 `json:"height"` //身高
Weight float32 `json:"weight"` //体重
}
解析以上结构体后,生成如下代码:
// 自动生成
const (
SomeTableTableName = "cms.some_table"
SomeTableId = "id"
SomeTableHeight = "height"
SomeTableWeight = "weight"
)
可以看到,生成了这个结构体中每个字段对应的常量值,这样有什么作用呢?主要是在一些 ORM 框架中,虽然杜绝了直接写 SQL,但也会有写死字段名的情况,如下例所示:
func FindHeight(id int){
// 只取这两个字段
db.Select("id","height").Find(&SomeTable{},id)
}
func FindWeight(id int){
db.Select("id","weight").Find(&SomeTable{},id)
}
// 这种通用的Select就更难管理了
func FindBy(id int,selects []string){
db.Select(selects).Find(&SomeTable{},id)
}
可以看到,假如我只想去两个字段,还得把字段名写死在代码中。如果是大型的项目,这就有些不好管理了,万一出现一些改名、删字段的极端情况,还得去代码中搜索,也容易遗漏。所以我们最好能把这个数据库字段名提取出来作为常量,利用 IDE 管理起来就很方便了。
a := FindBy(1,[]string{SomeTableId,SomeTableHeight})
这样,即保证了灵活性,也不担心项目里到处都是写死的数据库字段名。那么对于表多、字段多的情况,使用 gopo
自动生成就很方便了。
gopo
的原理也很简单,就是解析 go 的 AST 语法树,然后生成对应的代码,实现的思路和代码都借鉴了 swaggo/swag,这是一个很牛逼的项目,在此表示感谢。
gopo
的使用也很简单,提供了很多可选参数,最简单用法就是:
$ gopo
那么它就会自动在当前目录下寻找 go 文件,收集里面的所有结构体,并为每个结构体生成对应的常量表。更多用法在项目的 README.md 中有说明,也可以通过 --help
去查看此命令的帮助文档。
[Goreleaser&TraivsCI]
进入本文的压轴,其实对 go 语言来说,还有一块很适合的应用就是编写一些命令行程序,简直不要太方便。代码编写完成后,打包直接能生成 Liunx\Mac\Windows 三大平台的可执行文件,也不需要考虑安装环境、语言版本等问题,比 Python、Java 什么的方便太多。当然这里不是想挑起语言之争,只是单说在打包、编译方面,go 做的比较好。
那么如果加上 goreleaser 和 CI,代码一推上去直接打包完毕同时更新到 homebrew、scoop 等包管理软件上,就更加的便捷了。这个项目的 .goreleaser.yml
和 .traivs.yml
这两个配置,基本上其他的 go 语言编写的命令行程序也可以直接拿来使用,有需要者自取即可。
简单介绍一下这整个流程:
- TraivsCI 检测到代码提交,自动运行打包任务
- 打包任务调用 goreleaser 进行打包
- 通过
.goreleaser.yml
中的配置,goreleaser 命令会自动打包并发到 github 的release
模块,并且推送到homebrew
或者scoop
等包管理工具上。
这里要注意的就是两点:
- TravisCI 中需要设置 github 的 personal access token,因为 goreleaser 需要往 github 上推包。
在图片上红圈标注的位置点击 Setting
,然后在 Environment Variables
中加一项 GITHUB_TOKEN
即可。
.goreleaser.yml
会自动建立homebrew
、scoop
的 repo,如果直接拿过来是不行的(这是我的账号下的配置),需要一定的修改:
before:
hooks:
# You may remove this if you don't use go modules.
- go mod download
builds:
- env:
- CGO_ENABLED=0
main: cmd/main.go
goos:
- linux
- darwin
- windows
goarch:
- 386
- amd64
archives:
- name_template: '{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
replacements:
darwin: Darwin
linux: Linux
windows: Windows
386: i386
amd64: x86_64
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ .Tag }}-next"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
brews:
-
# 项目名
name: gopo
# Github repository 需要改成自己的
tap:
owner: HYY-yu
name: homebrew-tap
# 需要改成自己的
url_template: "https://github.com/HYY-yu/gopo/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
# Git author used to commit to the repository.
# Defaults are shown.
commit_author:
name: goreleaserbot
email: goreleaser@carlosbecker.com
# Folder inside the repository to put the formula.
# Default is the root folder.
folder: Formula
# Caveats for the user of your binary.
# Default is empty.
caveats: "gopo -v"
# Your app's homepage.
# Default is empty.
# homepage: "https://example.com/"
# Your app's description.
# Default is empty.
description: "Gopo"
# Specify for packages that run as a service.
# Default is empty.
plist: |
<?xml version="1.0" encoding="UTF-8"?>
...
# Custom install script for brew.
# Default is 'bin.install "program"'.
install: |
system "rm -f #{bin}/gopo"
bin.install "gopo"
scoop:
# 需要改成自己的
url_template: "https://github.com/HYY-yu/gopo/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
# Repository to push the app manifest to.
bucket:
owner: HYY-yu
name: scoop-bucket
# Git author used to commit to the repository.
# Defaults are shown.
commit_author:
name: goreleaserbot
email: goreleaser@carlosbecker.com
# The project name and current git tag are used in the format string.
commit_msg_template: "Scoop update for {{ .ProjectName }} version {{ .Tag }}"
# Persist data between application updates
persist:
- "data"
- "config.toml"
总结
那么 Goreleaser+TraivsCI 整个流程基本也介绍完毕了,现在只需要为 master 分支打一个 tag,比如 v0.2.0
,那么直接就会生成对应版本的可执行文件,并发布出去。
使用者利用 brew upgrade gopo
更新即可。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于