‍PowerProto: gRPC工具链(protoc, protoc-gen-go)的一键安装与版本控制

中文 | English

项目地址:An awesome version control tool for protoc and its related plugins. (github.com/storyicon/powerproto)

PowerProto主要用于解决下面三个问题:

  1. 降低gRPC的使用门槛与使用成本。
  2. 解决protoc以及其相关插件(比如protoc-gen-go、protoc-gen-grpc-gateway)的版本控制问题。
  3. 高效管理proto的编译,实现多平台兼容、一键安装与编译。

功能

  1. 实现protoc的一键安装与多版本管理。
  2. 实现protoc相关插件(比如protoc-gen-go)的一键安装与多版本管理。
  3. 通过配置文件管理proto的编译,而非shell脚本,提高可读性与兼容性。
  4. 引导式生成配置文件,跨平台兼容,一份配置在多个平台均可以实现一键编译。
  5. 支持批量、递归编译proto文件,提高效率。
  6. 跨平台支持PostAction,可以在编译完成之后执行一些常规操作(比如替换掉所有生成文件中的"omitempty")。
  7. 支持PostShell,在编译完成之后执行特定的shell脚本。
  8. 支持 google api, gogo protobuf 等的一键安装与版本控制。

安装与依赖

  1. 目前版本的 PowerProto 依赖 go(>=1.16) 以及 git(未来可能会直接使用CDN拉取构建好的二进制),请确保运行环境中包含这两个命令。
  2. protoc的下载源是Github,PowerProto在下载protoc时尊重 HTTP_PROXYHTTPS_PROXY环境变量,如果遇到网络问题,请自行配置代理。
  3. 在查询protoc的版本列表时,会对github.com使用git ls-remote,如果遇到网络问题,请自行为git配置代理。
  4. 在当前版本,下载和查询插件版本均依赖go命令,所以如果遇到网络问题,请自行配置 GOPROXY环境变量。
  5. 默认会使用 用户目录/.powerproto作为安装目录,用于放置下载好的各种插件以及全局配置,可以通过 POWERPROTO_HOME环境变量来修改安装目录。
  6. 如果认为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]

整理配置主要包含两个操作:

  1. 通过查询,将版本中的latest替换为真实的最新版本号。
  2. 安装配置文件中定义的所有依赖。

支持通过 -d 参数来进入到debug模式,查看更详细的日志。

三、编译Proto文件

可以通过下面的命令进行Proto文件的编译:

// 编译指定的proto文件
powerproto build xxxx.proto // 编译当前目录下的所有proto文件
powerproto build . // 递归编译当前目录下的所有proto文件,包括子文件夹。
powerproto build -r .

其执行逻辑是,对于每一个proto文件,从其文件所在目录开始向父级目录寻找 powerproto.yaml 配置文件:

  1. 对于找到的配置文件,与其中的scope进行匹配,如果匹配则采用。
  2. 检查并安装配置文件中声明的依赖。
  3. 根据配置文件中的pluginsprotocoptionsimportPaths等配置对proto文件进行编译。 当所有的proto文件都编译完成之后,如果你指定了 -p 参数,还会进行PostActionPostShell的执行。

注意: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 参数,才会执行配置文件中定义的PostActionPostShell

目前,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)的一键安装与版本控制的更多相关文章

  1. X86上搭建交叉工具链,来给龙芯笔记本编译本地工具链(未完待续)

    故事的背景是,我买了一台龙芯2F的笔记本来装B. 为什么说是装B呢?因为不但操作系统是Linux,而且CPU还是龙芯的. 一般人有这么酷的装备吗?简直是装B大圣啊. 这里一定要申明一点,本人不是IT技 ...

  2. X86给龙芯笔记本编译本地工具链(未完待续)

    我买了一台龙芯2F的笔记本来当玩具. 买回来发现,这台笔记本上没法安装软件,因为既没有软件仓库,也没有GCC. 因此需要构建交叉工具链和构建本地工具链. 下面是我研究如何搞定着一切的笔记. 工具链组件 ...

  3. xmake v2.3.7 发布, 新增 tinyc 和 emscripten 工具链支持

    xmake 是一个基于 Lua 的轻量级跨平台构建工具,使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能 ...

  4. Atitit 项目管理(5)----------后勤管理与工具链支持管理

    Atitit 项目管理(5)----------后勤管理与工具链支持管理 1.1. keyword1 1.2. 15个辅助软件1 1.3. 公共模块管理(100个即可)2 1.4. 第三方类库表2 1 ...

  5. gcc工具链简述

    工具链软件包括BINUTILS.GCC.GLIBC.GDB等. BINUTILS是二进制程序处理工具,包括链接器.汇编器等目标程序处理的工具. GCC(GNU Compiler Collection) ...

  6. CROSSTOOL-NG建立交叉编译工具链

    CROSSTOOL-NG建立交叉编译工具链 因为考试和学习的原因我已经一段时间没有玩我的JZ2440,现在终于考完试了,我再次找出了我的JZ2440.我之前学习的时候使用的是韦东山老师提供的开发工具, ...

  7. Crosstool-ng制作交叉编译工具链

    Crosstool-ng制作交叉编译工具链 交叉编译器可以用现成的,比如CodeSourcery制作的交叉编译器,也可以自己制作,一般是用kernel+gcc+glibc+binutils的源码包来编 ...

  8. linux 学习笔记 GNU工具链简介

    我们通常无法直接通过Linux内核,而需要借助Linux内核之上的GUN工具链来进行 文件处理 文本操作 进程管理 等操作. GNU/Linux shell为用户提供了 启动程序 管理文件系统上的文件 ...

  9. 【原创】如何构建MIPS交叉编译工具链

    运行环境:Ubuntu12.04PC提前安装库:flex,bison,libncureses5-dev,texinfo,这些库提前apt-get install.需要重新安装:gawk(先apt-ge ...

随机推荐

  1. 俄罗斯方块(c++)

    这个俄罗斯方块是用c++基于windows控制台制作的. 源码地址:https://github.com/Guozhi-explore 话不多说,先上图感受一下:(控制台丑陋的界面不是我的锅emmm) ...

  2. 『动善时』JMeter基础 — 45、脚本录制工具Badboy介绍

    目录 1.Badboy软件介绍 2.Badboy下载 3.Badboy安装 4.Badboy界面介绍 (1)菜单栏: (2)工具栏: (3)左下角界面视图: 1.Badboy软件介绍 Badboy是一 ...

  3. 管中窥豹-ssh链接过多的问题分析及复盘

    缘起 某一天,产品侧同事联系过来,反馈话单传输程序报错,现象如下: 实际上,该节点仅提供了一个sftp服务,供产品侧传输话单过来进行临时存储,由计费部门取走而已. 分析 于是找运维同事上服务器看了下情 ...

  4. 关于kubernetes的十七个实验(一)

    实验综述 Kubernetes用来管理云平台上的容器化应用,这里从 https://www.katacoda.com/courses/kubernetes 学习Kubernetes的使用,对Kuber ...

  5. 禁止特定IP访问Oracle数据库

    通过使用数据库服务器端的sqlnet.ora文件可以实现禁止指定IP主机访问数据库的功能,这对于提升数据库的安全性有很大的帮助,与此同时,这个技术为我们管理和约束数据库访问控制提供了有效的手段 在sq ...

  6. 将Winform和wpf的界面转换为CPF代码用来实现跨平台

    CPF的设计器里带界面代码转换功能,将运行中的Winform或者wpf的程序界面转换为cpf代码,主要转换控件类型和布局,默认支持的是常用的原生控件.不支持Netcore,只支持.Netframewo ...

  7. 一个例子让你秒懂 Qt Creator 编译原理

    小北师兄作品 首发于微信公众号 小北师兄 微信 ID: ncuneupa 由于排版原因,文章可能读起来不太清晰,如果想看更好的排版,可以来我的公众号:小北师兄 大家好,我是你们的小北师兄,由于工作原因 ...

  8. 五、JavaSE语言基础之流程控制

    流程控制的简单概念 流程控制:指通过关键字控制代码的执行流程; 一.顺序结构:执行顺序从左到右从上到下; 顺序结构无关键字,一般而言大多数代码都是顺序结构; 二.选择结构:根据条件判断是否执行 选择结 ...

  9. iOS如何提升,首先得知自己的处境!(欢迎评论留言)

    聊聊行情?为什么总有人在乎旁人的看法而忽略自己的初衷?虽然iOS开发市场说不上好但也绝不算坏,想没想过那些煽风点火说iOS不行的人在做什么?真的转行从头开始?错.大错特错!在劝退你的同时他们会默默的学 ...

  10. Vue Element-ui表单校验规则,你掌握了哪些?

    1.前言   Element-ui表单校验规则,使得错误提示可以直接在form-item下面显示,无需弹出框,因此还是很好用的.   我在做了登录页面的表单校验后,一度以为我已经很了解表单的校验规则. ...