PowerProto: gRPC工具链(protoc, protoc-gen-go)的一键安装与版本控制
PowerProto: gRPC工具链(protoc, protoc-gen-go)的一键安装与版本控制
中文 | English
PowerProto主要用于解决下面三个问题:
- 降低gRPC的使用门槛与使用成本。
- 解决protoc以及其相关插件(比如protoc-gen-go、protoc-gen-grpc-gateway)的版本控制问题。
- 高效管理proto的编译,实现多平台兼容、一键安装与编译。
功能
- 实现protoc的一键安装与多版本管理。
- 实现protoc相关插件(比如protoc-gen-go)的一键安装与多版本管理。
- 通过配置文件管理proto的编译,而非shell脚本,提高可读性与兼容性。
- 引导式生成配置文件,跨平台兼容,一份配置在多个平台均可以实现一键编译。
- 支持批量、递归编译proto文件,提高效率。
- 跨平台支持PostAction,可以在编译完成之后执行一些常规操作(比如替换掉所有生成文件中的"omitempty")。
- 支持PostShell,在编译完成之后执行特定的shell脚本。
- 支持 google api, gogo protobuf 等的一键安装与版本控制。
安装与依赖
- 目前版本的
PowerProto
依赖go
(>=1.16) 以及git
(未来可能会直接使用CDN拉取构建好的二进制),请确保运行环境中包含这两个命令。 protoc
的下载源是Github,PowerProto
在下载protoc
时尊重HTTP_PROXY
、HTTPS_PROXY
环境变量,如果遇到网络问题,请自行配置代理。- 在查询
protoc
的版本列表时,会对github.com
使用git ls-remote
,如果遇到网络问题,请自行为git
配置代理。 - 在当前版本,下载和查询插件版本均依赖
go
命令,所以如果遇到网络问题,请自行配置GOPROXY
环境变量。 - 默认会使用
用户目录/.powerproto
作为安装目录,用于放置下载好的各种插件以及全局配置,可以通过POWERPROTO_HOME
环境变量来修改安装目录。 - 如果认为
powerproto
名字太长,可以通过alias
成一个更简单的名字来提高输入效率,比如没有人会介意你叫它pp
。
一、通过Go进行安装
直接执行下面的命令即可进行安装:
go install github.com/storyicon/powerproto/cmd/powerproto@latest
二、开箱即用版本
可以通过 Github Release Page
下载开箱即用版本。
命令介绍
你可以通过 powerproto -h 来查看帮助,比如:
powerproto -h
powerproto init -h
powerproto tidy -h
powerproto build -h
powerproto env -h
它的好处是命令行中的文档永远和你的二进制版本保持一致。而Github上的文档可能会一直是对应最新的二进制。
一、初始化配置
可以通过下面的命令进行配置的初始化:
powerproto init
二、整理配置
可以通过下面的命令整理配置:
powerproto tidy
它将会从当前目录开始向父级目录搜索名为 powerproto.yaml
的配置文件,并对配置进行读取和整理。
你也可以指定整理哪个配置文件:
powerproto tidy [the path of proto file]
整理配置主要包含两个操作:
- 通过查询,将版本中的latest替换为真实的最新版本号。
- 安装配置文件中定义的所有依赖。
支持通过 -d
参数来进入到debug模式
,查看更详细的日志。
三、编译Proto文件
可以通过下面的命令进行Proto文件的编译:
// 编译指定的proto文件
powerproto build xxxx.proto
// 编译当前目录下的所有proto文件
powerproto build .
// 递归编译当前目录下的所有proto文件,包括子文件夹。
powerproto build -r .
其执行逻辑是,对于每一个proto文件,从其文件所在目录开始向父级目录寻找 powerproto.yaml
配置文件:
- 对于找到的配置文件,与其中的
scope
进行匹配,如果匹配则采用。 - 检查并安装配置文件中声明的依赖。
- 根据配置文件中的
plugins
、protoc
、options
、importPaths
等配置对proto文件进行编译。 当所有的proto文件都编译完成之后,如果你指定了-p
参数,还会进行PostAction
与PostShell
的执行。
注意:protoc
执行的工作目录默认是proto文件
匹配到的配置文件所在的目录,它相当于你在配置文件所在目录执行protoc命令。你可以通过配置文件中的 protocWorkDir
来进行修改。
支持通过 -d
参数来进入到debug模式
,查看更详细的日志。
支持通过 -y
参数来进入到dryRun模式
,只打印命令而不真正执行,这对于调试非常有用。
四、查看环境变量
如果你的命令一直卡在某个状态,大概率是出现网络问题了。
你可以通过下面的命令来查看环境变量是否配置成功:
powerproto env
示例
比如你在 /mnt/data/hello
目录下拥有下面这样的文件结构:
$ pwd
/mnt/data/hello
$ tree
./apis
└── hello.proto
powerproto.yaml
powerproto.yaml
的文件内容是(你可以通过 powerproto init
命令很方便的生成配置文件):
scopes:
- ./
protoc: latest
protocWorkDir: ""
plugins:
protoc-gen-go: google.golang.org/protobuf/cmd/protoc-gen-go@latest
protoc-gen-go-grpc: google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
repositories:
GOOGLE_APIS: https://github.com/googleapis/googleapis@75e9812478607db997376ccea247dd6928f70f45
options:
- --go_out=.
- --go_opt=paths=source_relative
- --go-grpc_out=.
- --go-grpc_opt=paths=source_relative
importPaths:
- .
- $GOPATH
- $POWERPROTO_INCLUDE
- $GOOGLE_APIS/github.com/googleapis/googleapis
postActions: []
postShell: ""
在任意目录执行:
powerproto build -r /mnt/data/hello/apis
你都可以得到编译后的文件
$ pwd
/mnt/data/hello
$ tree
./apis
├── hello.pb.go
├── hello.proto
└── hello_grpc.pb.go
powerproto.yaml
它相当于你在 powerproto.yaml
所在目录,执行:
$POWERPROTO_HOME/protoc/3.17.3/protoc --go_out=. \
--go_opt=paths=source_relative \
--go-grpc_out=. \
--go-grpc_opt=paths=source_relative \
--proto_path=/mnt/data/hello \
--proto_path=$GOPATH \
--proto_path=$POWERPROTO_HOME/include \
--proto_path=$POWERPROTO_HOME/gits/75e9812478607db997376ccea247dd6928f70f45/github.com/googleapis/googleapis \
--plugin=protoc-gen-go=$POWERPROTO_HOME/plugins/google.golang.org/protobuf/cmd/protoc-gen-go@v1.27.1/protoc-gen-go \
--plugin=protoc-gen-go-grpc=$POWERPROTO_HOME/plugins/google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1.0/protoc-gen-go-grpc
/mnt/data/hello/apis/hello.proto
更多的例子可以参考 示例.
配置文件
配置文件用于描述编译proto文件时,各种依赖的版本以及参数等。
可以方便的通过 powerproto init
进行配置文件的初始化。
解释
以下面这份配置文件为例:
# 必填,scopes 用于定义作用域,即当前配置项对项目中的哪些目录生效
scopes:
- ./
# 必填,protoc的版本,可以填 latest,会自动转换成最新的版本
protoc: 3.17.3
# 选填,执行protoc命令的工作目录,默认是配置文件所在目录
# 支持路径中混用环境变量,比如$GOPATH
protocWorkDir: ""
# 选填,定义依赖的Git存储库
# 一般用于公共的protobuf库的依赖控制
repositories:
# 定义依赖 27156597fdf4fb77004434d4409154a230dc9a32 版本的 https://github.com/googleapis/googleapis
# 并且定义其名字为 GOOGLE_APIS
# 在 importPaths 中可以通过 $GOOGLE_APIS 来引用它
GOOGLE_APIS: https://github.com/googleapis/googleapis@27156597fdf4fb77004434d4409154a230dc9a32
# 定义依赖 226206f39bd7276e88ec684ea0028c18ec2c91ae 版本的 https://github.com/gogo/protobuf
# 并且定义其名字为 GOGO_PROTOBUF
# 在 importPaths 中可以通过 $GOGO_PROTOBUF 来引用它
GOGO_PROTOBUF: https://github.com/gogo/protobuf@226206f39bd7276e88ec684ea0028c18ec2c91ae
# 必填,代表scope匹配的目录中的proto文件,在编译时需要用到哪些插件
plugins:
# 插件的名字、路径以及版本号。
# 插件的地址必须是 path@version 的格式,version可以填latest,会自动转换成最新的版本。
protoc-gen-deepcopy: istio.io/tools/cmd/protoc-gen-deepcopy@latest
protoc-gen-go: google.golang.org/protobuf/cmd/protoc-gen-go@latest
protoc-gen-go-json: github.com/mitchellh/protoc-gen-go-json@v1.0.0
protoc-gen-grpc-gateway: github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@v2.5.0
# 必填,定义了编译proto文件时 protoc 的参数
options:
- --go_out=paths=source_relative:.
- --go-json_out=.
- --deepcopy_out=source_relative:.
- --grpc-gateway_out=.
- --go-grpc_out=paths=source_relative:.
# 必填,定义了构建时 protoc 的引用路径,会被转换为 --proto_path (-I) 参数。
importPaths:
# 特殊变量。代表当前配置文件所在文件夹
- .
# 环境变量。可以使用环境变量
# 也支持 $GOPATH/include 这样的混合写法
- $GOPATH
- $POWERPROTO_INCLUDE
# 特殊变量。引用待编译的proto文件所在的目录
# 比如将要编译 /a/b/data.proto,那么 /a/b 目录将会被自动引用
- $SOURCE_RELATIVE
# 引用 repositories 中的 GOOGLE_APIS
- $GOOGLE_APIS/github.com/googleapis/googleapis
# 引用 repositories 中的 GOGO_PROTOBUF
- $GOGO_PROTOBUF
# 选填,构建完成之后执行的操作,工作目录是配置文件所在目录
# postActions是跨平台兼容的
# 注意,必须在 powerproto build 时附加 -p 参数,才会执行配置文件中的postActions
postActions: []
# 选填,构建完成之后执行的shell脚本,工作目录是配置文件所在目录
# postShell不是跨平台兼容的。
# 注意,必须在 powerproto build 时附加 -p 参数,才会执行配置文件中的postShell
postShell: |
// do something
匹配模式与工作目录
在构建proto文件时,将会从proto文件所在目录开始,向父级目录搜索 powerproto.yaml
配置文件,并与其中的 scope进行匹配,第一个匹配到的配置,将会被用于此proto文件的编译。
在执行protoc时(执行postActions、postShell时也是如此),是以配置文件所在目录作为工作目录的,即相当于你在这个目录执行protoc命令。
多配置组合
一个配置文件中支持填写多份配置,多份配置之间以 "---" 进行分割。
在下面的示例中,apis1目录使用的是v1.25.0的protoc-gen-go,而apis2目录使用的则是v1.27.0的protoc-gen-go。
scopes:
- ./apis1
protoc: v3.17.3
protocWorkDir: ""
plugins:
protoc-gen-go: google.golang.org/protobuf/cmd/protoc-gen-go@v1.25.0
protoc-gen-go-grpc: google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1.0
repositories:
GOOGLE_APIS: https://github.com/googleapis/googleapis@75e9812478607db997376ccea247dd6928f70f45
options:
- --go_out=.
- --go_opt=paths=source_relative
- --go-grpc_out=.
- --go-grpc_opt=paths=source_relative
importPaths:
- .
- $GOPATH
- $POWERPROTO_INCLUDE
- $GOOGLE_APIS/github.com/googleapis/googleapis
postActions: []
postShell: ""
---
scopes:
- ./apis2
protoc: v3.17.3
protocWorkDir: ""
plugins:
protoc-gen-go: google.golang.org/protobuf/cmd/protoc-gen-go@v1.27.0
protoc-gen-go-grpc: google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1.0
repositories:
GOOGLE_APIS: https://github.com/googleapis/googleapis@75e9812478607db997376ccea247dd6928f70f45
options:
- --go_out=.
- --go_opt=paths=source_relative
- --go-grpc_out=.
- --go-grpc_opt=paths=source_relative
importPaths:
- .
- $GOPATH
- $POWERPROTO_INCLUDE
- $GOOGLE_APIS/github.com/googleapis/googleapis
postActions: []
postShell: ""
PostAction
PostAction允许在所有的proto文件都编译完成之后,执行特定的操作。与PostShell
相比,它是跨平台支持的。
为了安全起见,只有在执行 powerproto build
时附加上 -p
参数,才会执行配置文件中定义的PostAction
与PostShell
。
目前,PostAction支持下面这些命令:
命令 | 描述 | 函数原型 |
---|---|---|
copy | 复制文件或文件夹 | copy(src string, dest string) error |
move | 移动文件或文件夹 | move(src string, dest string) error |
remove | 删除文件或文件夹 | remove(path ...string) error |
replace | 批量替换文件中的字符串 | replace(pattern string, from string, to string) error |
1. copy
用于复制文件或文件夹,其函数原型为:
copy(src string, dest string) error
为了安全以及配置的兼容性,参数中只允许填写相对路径。
如果目标文件夹已经存在,将会合并。
下面的例子将会把配置文件所在目录下的a复制到b:
postActions:
- name: copy
args:
- ./a
- ./b
2. move
用于移动文件或文件夹,其函数原型为:
move(src string, dest string) error
为了安全以及配置的兼容性,参数中只允许填写相对路径。
如果目标文件夹已经存在,将会合并。
下面的例子将会把配置文件所在目录下的a移动到b:
postActions:
- name: move
args:
- ./a
- ./b
3. remove
用于删除文件或文件夹,其函数原型为:
remove(path ...string) error
为了安全以及配置的兼容性,参数中只允许填写相对路径。
下面的例子将会删除配置文件所在目录下的a、b、c:
postActions:
- name: remove
args:
- ./a
- ./b
- ./c
4. replace
用于批量替换文件中的字符串,其函数原型为:
replace(pattern string, from string, to string) error
其中:
- pattern是支持通配符的相对路径。
- from是要被替换的字符串。
- to是替换为的字符串。
下面的例子将会把apis目录以及其子目录下的所有go文件中的 ,omitempty
替换为空字符串:
postActions:
- name: replace
args:
- ./apis/**/*.go
- ',omitempty'
- ""
PowerProto: gRPC工具链(protoc, protoc-gen-go)的一键安装与版本控制的更多相关文章
- X86上搭建交叉工具链,来给龙芯笔记本编译本地工具链(未完待续)
故事的背景是,我买了一台龙芯2F的笔记本来装B. 为什么说是装B呢?因为不但操作系统是Linux,而且CPU还是龙芯的. 一般人有这么酷的装备吗?简直是装B大圣啊. 这里一定要申明一点,本人不是IT技 ...
- X86给龙芯笔记本编译本地工具链(未完待续)
我买了一台龙芯2F的笔记本来当玩具. 买回来发现,这台笔记本上没法安装软件,因为既没有软件仓库,也没有GCC. 因此需要构建交叉工具链和构建本地工具链. 下面是我研究如何搞定着一切的笔记. 工具链组件 ...
- xmake v2.3.7 发布, 新增 tinyc 和 emscripten 工具链支持
xmake 是一个基于 Lua 的轻量级跨平台构建工具,使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能 ...
- Atitit 项目管理(5)----------后勤管理与工具链支持管理
Atitit 项目管理(5)----------后勤管理与工具链支持管理 1.1. keyword1 1.2. 15个辅助软件1 1.3. 公共模块管理(100个即可)2 1.4. 第三方类库表2 1 ...
- gcc工具链简述
工具链软件包括BINUTILS.GCC.GLIBC.GDB等. BINUTILS是二进制程序处理工具,包括链接器.汇编器等目标程序处理的工具. GCC(GNU Compiler Collection) ...
- CROSSTOOL-NG建立交叉编译工具链
CROSSTOOL-NG建立交叉编译工具链 因为考试和学习的原因我已经一段时间没有玩我的JZ2440,现在终于考完试了,我再次找出了我的JZ2440.我之前学习的时候使用的是韦东山老师提供的开发工具, ...
- Crosstool-ng制作交叉编译工具链
Crosstool-ng制作交叉编译工具链 交叉编译器可以用现成的,比如CodeSourcery制作的交叉编译器,也可以自己制作,一般是用kernel+gcc+glibc+binutils的源码包来编 ...
- linux 学习笔记 GNU工具链简介
我们通常无法直接通过Linux内核,而需要借助Linux内核之上的GUN工具链来进行 文件处理 文本操作 进程管理 等操作. GNU/Linux shell为用户提供了 启动程序 管理文件系统上的文件 ...
- 【原创】如何构建MIPS交叉编译工具链
运行环境:Ubuntu12.04PC提前安装库:flex,bison,libncureses5-dev,texinfo,这些库提前apt-get install.需要重新安装:gawk(先apt-ge ...
随机推荐
- 【NX二次开发】根据视图名称获取视图的矩阵
函数:uc6433 () 函数说明:获取视图名称对应的矩阵值.视图名称分为几类: 1. 制图中的视图,右键属性可以查看名称 获取上图中的视图的矩阵: 1 double v_mtx[9] = { 1.0 ...
- 【SQLite】SQLite文件突然变大怎么办?瘦身办法
使用VACUUM命令即可: VACUUM 命令通过复制主数据库中的内容到一个临时数据库文件,然后清空主数据库,并从副本中重新载入原始的数据库文件.这消除了空闲页,把表中的数据排列为连续的,另外会清理数 ...
- DHCP原理与配置
一.DHCP应用场景 DHCP服务器能够为大量主机分配lp地址,并能够集中管理 二.DHCP报文类型 微软操作系统的DHCP服务是四个广播报文 三.地址池 主机-------------------- ...
- 6.17考试总结(NOIP模拟8)[星际旅行·砍树·超级树·求和]
6.17考试总结(NOIP模拟8) 背景 考得不咋样,有一个非常遗憾的地方:最后一题少取膜了,\(100pts->40pts\),改了这么多年的错还是头一回看见以下的情景... T1星际旅行 前 ...
- 「10.15」梦境(贪心)·玩具(神仙DP)·飘雪圣域(主席树\树状数组\莫队)
A. 梦境 没啥可说的原题.... 贪心题的常见套路我们坐标以左端点为第一关键字,右端点为第二关键字 然后对于每个转折点,我们现在将梦境中左端点比他小的区间放进$multiset$里 然后找最近的右端 ...
- 基于SpringBoot 、AOP与自定义注解转义字典值
一直以来,前端展示字典一般以中文展示为主,若在表中存字典值中文,当字典表更改字典值对应的中文,会造成数据不一致,为此设置冗余字段并非最优方案,若由前端自己写死转义,不够灵活,若在业务代码转义,臃肿也不 ...
- 通过Cloudflare API进行CDN刷新
1.Cloudflare CDN刷新说明 1.Cloudfalre同Akamai一样,只有刷新,没有预热的概念. 2.通过Cloudflare API进行刷新,需要用到登录用户的[邮箱][api密钥] ...
- testt
一级标题 二级标题 三级标题 四级标题 l 1
- python3.6虚拟环境
3.1.安装python3.6 [root@slavenode1 ~]# python -V Python 2.7.5 [root@slavenode1 ~]# yum install python3 ...
- 9.5、zabbix高级操作(1)
在zabbix-web中删除之前所有监控的主机: 1.zabbix自动发现配置: zabbix-server通过扫描指定范围的ip地址发现zabbix-agent并自动添加监控主机,适用于zabbix ...