powerproto/README_CN.md
storyicon 9aac714c32
init
Signed-off-by: storyicon <yuanchao@bilibili.com>
2021-07-21 00:24:43 +08:00

430 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# PowerProto
[![Go Report Card](https://goreportcard.com/badge/github.com/storyicon/powerproto?t=1)](https://goreportcard.com/report/github.com/storyicon/powerproto) ![TotalLine](https://img.shields.io/tokei/lines/github/storyicon/powerproto?color=77%2C199%2C31) ![last-commit](https://img.shields.io/github/last-commit/storyicon/powerproto) [![GoDoc](https://godoc.org/github.com/storyicon/powerproto?status.svg)](https://godoc.org/github.com/storyicon/powerproto)
**中文** | [English](README_CN.md)
![exmpales](./docs/images/exmaple.gif)
PowerProto主要用于解决下面三个问题
1. 降低gRPC的使用门槛与使用成本。
2. 解决protoc以及其相关插件比如protoc-gen-go、protoc-gen-grpc-gateway的版本控制问题。
3. 高效管理proto的编译实现多平台兼容、一键安装与编译。
- [PowerProto](#powerproto)
- [功能](#功能)
- [安装与依赖](#安装与依赖)
- [一、通过Go进行安装](#一通过go进行安装)
- [二、开箱即用版本](#二开箱即用版本)
- [命令介绍](#命令介绍)
- [一、初始化配置](#一初始化配置)
- [二、整理配置](#二整理配置)
- [三、编译Proto文件](#三编译proto文件)
- [示例](#示例)
- [配置文件](#配置文件)
- [解释](#解释)
- [匹配模式与工作目录](#匹配模式与工作目录)
- [多配置组合](#多配置组合)
- [PostAction](#postaction)
- [1. copy](#1-copy)
- [2. move](#2-move)
- [3. remove](#3-remove)
- [4. replace](#4-replace)
## 功能
1. 实现protoc的一键安装与多版本管理。
2. 实现protoc相关插件比如protoc-gen-go的一键安装与多版本管理。
3. 通过配置文件管理proto的编译而非shell脚本提高可读性与兼容性。
4. 引导式生成配置文件,跨平台兼容,一份配置在多个平台均可以实现一键编译。
5. 支持批量、递归编译proto文件提高效率。
6. 跨平台支持PostAction可以在编译完成之后执行一些常规操作比如替换掉所有生成文件中的"omitempty")。
7. 支持PostShell在编译完成之后执行特定的shell脚本。
## 安装与依赖
1. 目前版本的 `PowerProto` 依赖 `go` 以及 `git`未来可能会直接使用CDN拉取构建好的二进制请确保运行环境中包含这两个命令。
2. `protoc`的下载源是Github`PowerProto`在下载`protoc`时尊重 `HTTP_PROXY``HTTPS_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
```
它的好处是命令行中的文档永远和你的二进制版本保持一致。而Github上的文档可能会一直是对应最新的二进制。
### 一、初始化配置
可以通过下面的命令进行配置的初始化:
```
powerproto init
```
### 二、整理配置
可以通过下面的命令整理配置:
```
powerproto tidy
```
它将会从当前目录开始向父级目录搜索名为 `powerproto.yaml` 的配置文件,并对配置进行读取和整理。
你也可以指定整理哪个配置文件:
```
powerproto tidy [the path of proto file]
```
整理配置主要包含两个操作:
1. 通过查询将版本中的latest替换为真实的最新版本号。
2. 安装配置文件中定义的所有依赖。
### 三、编译Proto文件
可以通过下面的命令进行Proto文件的编译
```
// 编译指定的proto文件
powerproto build xxxx.proto
// 编译当前目录下的所有proto文件
powerproto build .
// 递归编译当前目录下的所有proto文件包括子文件夹。
powerproto build -r .
```
其执行逻辑是对于每一个proto文件从其文件所在目录开始向父级目录寻找 `powerproto.yaml` 配置文件:
1. 对于找到的配置文件,与其中的`scope`进行匹配,如果匹配则采用。
2. 检查并安装配置文件中声明的依赖。
3. 根据配置文件中的`plugins``protoc``options``importPaths`等配置对proto文件进行编译。 当所有的proto文件都编译完成之后如果你指定了 `-p` 参数,还会进行`PostAction``PostShell`的执行。
注意:`protoc`执行的工作目录默认是`proto文件`匹配到的配置文件所在的目录它相当于你在配置文件所在目录执行protoc命令。你可以通过配置文件中的 `protocWorkDir` 来进行修改。
## 示例
比如你在 `/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
options:
- --go_out=.
- --go_opt=paths=source_relative
- --go-grpc_out=.
- --go-grpc_opt=paths=source_relative
importPaths:
- .
- $GOPATH
- $POWERPROTO_INCLUDE
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 \
--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`进行配置文件的初始化。
### 解释
以下面这份配置文件为例:
```yaml
# 必填scopes 用于定义作用域,即当前配置项对项目中的哪些目录生效
scopes:
- ./
# 必填protoc的版本可以填 latest会自动转换成最新的版本
protoc: 3.17.3
# 选填执行protoc命令的工作目录默认是配置文件所在目录
# 支持路径中混用环境变量,比如$GOPATH
protocWorkDir: ""
# 必填代表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) 参数。
# 支持混用环境变量,比如 $GOPATH/include。
# $POWERPROTO_INCLUDE是一个特殊变量指 $POWERPRTO/include里面包含了protoc默认提供的公共proto 文件。
# "." 是指配置文件所在文件夹。
importPaths:
- .
- $GOPATH
- $POWERPROTO_INCLUDE
# 选填,构建完成之后执行的操作,工作目录是配置文件所在目录
# 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
options:
- --go_out=.
- --go_opt=paths=source_relative
- --go-grpc_out=.
- --go-grpc_opt=paths=source_relative
importPaths:
- .
- $GOPATH
- $POWERPROTO_INCLUDE
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
options:
- --go_out=.
- --go_opt=paths=source_relative
- --go-grpc_out=.
- --go-grpc_opt=paths=source_relative
importPaths:
- .
- $GOPATH
- $POWERPROTO_INCLUDE
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
```yaml
postActions:
- name: copy
args:
- ./a
- ./b
```
#### 2. move
用于移动文件或文件夹,其函数原型为:
```
move(src string, dest string) error
```
为了安全以及配置的兼容性,参数中只允许填写相对路径。
如果目标文件夹已经存在,将会合并。
下面的例子将会把配置文件所在目录下的a移动到b
```yaml
postActions:
- name: move
args:
- ./a
- ./b
```
#### 3. remove
用于删除文件或文件夹,其函数原型为:
```
remove(path ...string) error
```
为了安全以及配置的兼容性,参数中只允许填写相对路径。
下面的例子将会删除配置文件所在目录下的a、b、c
```yaml
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'
- ""
```