mirror of
https://github.com/go-kratos/kratos.git
synced 2025-01-10 00:29:01 +02:00
add protoc gen ecode (#274)
* add protoc gen ecode * add protobuf example
This commit is contained in:
parent
c1f9b5ca81
commit
1481e14c12
1
.gitignore
vendored
1
.gitignore
vendored
@ -28,4 +28,5 @@ tool/kratos-gen-bts/kratos-gen-bts
|
||||
tool/kratos-gen-mc/kratos-gen-mc
|
||||
tool/kratos/kratos-protoc/kratos-protoc
|
||||
tool/kratos/protobuf/protoc-gen-bm/protoc-gen-bm
|
||||
tool/kratos/protobuf/protoc-gen-ecode/protoc-gen-ecode
|
||||
tool/kratos/protobuf/protoc-gen-bswagger/protoc-gen-bswagger
|
||||
|
@ -1,38 +1,31 @@
|
||||
### kratos tool protoc
|
||||
|
||||
```
|
||||
// generate all
|
||||
```shell
|
||||
# generate all
|
||||
kratos tool protoc api.proto
|
||||
// generate gRPC
|
||||
# generate gRPC
|
||||
kratos tool protoc --grpc api.proto
|
||||
// generate BM HTTP
|
||||
# generate BM HTTP
|
||||
kratos tool protoc --bm api.proto
|
||||
// generate swagger
|
||||
# generate ecode
|
||||
kratos tool protoc --ecode api.proto
|
||||
# generate swagger
|
||||
kratos tool protoc --swagger api.proto
|
||||
```
|
||||
执行对应生成 `api.pb.go/api.bm.go/api.swagger.json` 源文档。
|
||||
|
||||
> 该工具在Windows/Linux下运行,需提前安装好 protobuf 工具
|
||||
执行生成如 `api.pb.go/api.bm.go/api.swagger.json/api.ecode.go` 的对应文件,需要注意的是:`ecode`生成有固定规则,需要首先是`enum`类型,且`enum`名字要以`ErrCode`结尾,如`enum UserErrCode`。详情可见:[example](https://github.com/bilibili/kratos/tree/master/example/protobuf)
|
||||
|
||||
该工具实际是一段`shell`脚本,其中自动将`protoc`命令进行了拼接,识别了需要的`*.proto`文件和当前目录下的`proto`文件,最终会拼接为如下命令进行执行:
|
||||
> 该工具在Windows/Linux下运行,需提前安装好 [protobuf](https://github.com/google/protobuf) 工具
|
||||
|
||||
`kratos tool protoc`本质上是拼接好了`protoc`命令然后进行执行,在执行时会打印出对应执行的`protoc`命令,如下可见:
|
||||
|
||||
```shell
|
||||
export $KRATOS_HOME = kratos路径
|
||||
export $KRATOS_DEMO = 项目路径
|
||||
|
||||
// 生成:api.pb.go
|
||||
protoc -I$GOPATH/src:$KRATOS_HOME/third_party:$KRATOS_DEMO/api --gofast_out=plugins=grpc:$KRATOS_DEMO/api $KRATOS_DEMO/api/api.proto
|
||||
|
||||
// 生成:api.bm.go
|
||||
protoc -I$GOPATH/src:$KRATOS_HOME/third_party:$KRATOS_DEMO/api --bm_out=$KRATOS_DEMO/api $KRATOS_DEMO/api/api.proto
|
||||
|
||||
// 生成:api.swagger.json
|
||||
protoc -I$GOPATH/src:$KRATOS_HOME/third_party:$KRATOS_DEMO/api --bswagger_out=$KRATOS_DEMO/api $KRATOS_DEMO/api/api.proto
|
||||
protoc --proto_path=$GOPATH --proto_path=$GOPATH/github.com/bilibili/kratos/third_party --proto_path=. --bm_out=:. api.proto
|
||||
protoc --proto_path=$GOPATH --proto_path=$GOPATH/github.com/bilibili/kratos/third_party --proto_path=. --gofast_out=plugins=grpc:. api.proto
|
||||
protoc --proto_path=$GOPATH --proto_path=$GOPATH/github.com/bilibili/kratos/third_party --proto_path=. --bswagger_out=:. api.proto
|
||||
protoc --proto_path=$GOPATH --proto_path=$GOPATH/github.com/bilibili/kratos/third_party --proto_path=. --ecode_out=:. api.proto
|
||||
```
|
||||
|
||||
大家也可以参考该命令进行`proto`生成,也可以参考 [protobuf](https://github.com/google/protobuf) 官方参数。
|
||||
|
||||
|
||||
-------------
|
||||
|
||||
[文档目录树](summary.md)
|
||||
|
40
example/protobuf/api.bm.go
Normal file
40
example/protobuf/api.bm.go
Normal file
@ -0,0 +1,40 @@
|
||||
// Code generated by protoc-gen-bm v0.1, DO NOT EDIT.
|
||||
// source: api.proto
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
bm "github.com/bilibili/kratos/pkg/net/http/blademaster"
|
||||
"github.com/bilibili/kratos/pkg/net/http/blademaster/binding"
|
||||
)
|
||||
|
||||
// to suppressed 'imported but not used warning'
|
||||
var _ *bm.Context
|
||||
var _ context.Context
|
||||
var _ binding.StructValidator
|
||||
|
||||
var PathUserInfo = "/user.api.User/Info"
|
||||
|
||||
// UserBMServer is the server API for User service.
|
||||
type UserBMServer interface {
|
||||
Info(ctx context.Context, req *UserReq) (resp *InfoReply, err error)
|
||||
}
|
||||
|
||||
var UserSvc UserBMServer
|
||||
|
||||
func userInfo(c *bm.Context) {
|
||||
p := new(UserReq)
|
||||
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
|
||||
return
|
||||
}
|
||||
resp, err := UserSvc.Info(c, p)
|
||||
c.JSON(resp, err)
|
||||
}
|
||||
|
||||
// RegisterUserBMServer Register the blademaster route
|
||||
func RegisterUserBMServer(e *bm.Engine, server UserBMServer) {
|
||||
UserSvc = server
|
||||
e.GET("/user.api.User/Info", userInfo)
|
||||
}
|
17
example/protobuf/api.ecode.go
Normal file
17
example/protobuf/api.ecode.go
Normal file
@ -0,0 +1,17 @@
|
||||
// Code generated by protoc-gen-ecode v0.1, DO NOT EDIT.
|
||||
// source: api.proto
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/bilibili/kratos/pkg/ecode"
|
||||
)
|
||||
|
||||
// to suppressed 'imported but not used warning'
|
||||
var _ ecode.Codes
|
||||
|
||||
// UserErrCode ecode
|
||||
var (
|
||||
UserNotExist = ecode.New(-404)
|
||||
UserUpdateNameFailed = ecode.New(10000)
|
||||
)
|
1000
example/protobuf/api.pb.go
Normal file
1000
example/protobuf/api.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
33
example/protobuf/api.proto
Normal file
33
example/protobuf/api.proto
Normal file
@ -0,0 +1,33 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package user.api;
|
||||
|
||||
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
||||
|
||||
option go_package = "api";
|
||||
|
||||
enum UserErrCode {
|
||||
OK = 0;
|
||||
UserNotExist = -404;
|
||||
UserUpdateNameFailed = 10000;
|
||||
}
|
||||
|
||||
message Info {
|
||||
int64 mid = 1 [(gogoproto.jsontag) = "mid"];
|
||||
string name = 2 [(gogoproto.jsontag) = "name"];
|
||||
string sex = 3 [(gogoproto.jsontag) = "sex"];
|
||||
string face = 4 [(gogoproto.jsontag) = "face"];
|
||||
string sign = 5 [(gogoproto.jsontag) = "sign"];
|
||||
}
|
||||
|
||||
message UserReq {
|
||||
int64 mid = 1 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
|
||||
}
|
||||
|
||||
message InfoReply {
|
||||
Info info = 1;
|
||||
}
|
||||
|
||||
service User {
|
||||
rpc Info(UserReq) returns (InfoReply);
|
||||
}
|
96
example/protobuf/api.swagger.json
Normal file
96
example/protobuf/api.swagger.json
Normal file
@ -0,0 +1,96 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"title": "api.proto",
|
||||
"version": ""
|
||||
},
|
||||
"schemes": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"consumes": [
|
||||
"application/json",
|
||||
"multipart/form-data"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"paths": {
|
||||
"/user.api.User/Info": {
|
||||
"get": {
|
||||
"summary": "/user.api.User/Info",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "integer"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"data": {
|
||||
"$ref": "#/definitions/.user.api.InfoReply"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "mid",
|
||||
"in": "query",
|
||||
"required": true,
|
||||
"type": "integer"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"user.api.User"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
".user.api.Info": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"mid": {
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"sex": {
|
||||
"type": "string"
|
||||
},
|
||||
"face": {
|
||||
"type": "string"
|
||||
},
|
||||
"sign": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
".user.api.InfoReply": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"info": {
|
||||
"$ref": "#/definitions/.user.api.Info"
|
||||
}
|
||||
}
|
||||
},
|
||||
".user.api.UserReq": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"mid": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"mid"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
3
example/protobuf/gen.sh
Normal file
3
example/protobuf/gen.sh
Normal file
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
kratos tool protoc api.proto
|
@ -8,7 +8,7 @@ import (
|
||||
|
||||
const (
|
||||
_getBMGen = "go get -u github.com/bilibili/kratos/tool/protobuf/protoc-gen-bm"
|
||||
_bmProtoc = "protoc --proto_path=%s --proto_path=%s --proto_path=%s --bm_out=explicit_http=true:."
|
||||
_bmProtoc = "protoc --proto_path=%s --proto_path=%s --proto_path=%s --bm_out=:."
|
||||
)
|
||||
|
||||
func installBMGen() error {
|
||||
|
25
tool/kratos-protoc/ecode.go
Normal file
25
tool/kratos-protoc/ecode.go
Normal file
@ -0,0 +1,25 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
const (
|
||||
_getEcodeGen = "go get -u github.com/bilibili/kratos/tool/protobuf/protoc-gen-ecode"
|
||||
_ecodeProtoc = "protoc --proto_path=%s --proto_path=%s --proto_path=%s --ecode_out=:."
|
||||
)
|
||||
|
||||
func installEcodeGen() error {
|
||||
if _, err := exec.LookPath("protoc-gen-ecode"); err != nil {
|
||||
if err := goget(_getEcodeGen); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func genEcode(ctx *cli.Context) error {
|
||||
return generate(ctx, _ecodeProtoc)
|
||||
}
|
@ -27,6 +27,11 @@ func main() {
|
||||
Usage: "whether to use swagger for generation",
|
||||
Destination: &withSwagger,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "ecode",
|
||||
Usage: "whether to use ecode for generation",
|
||||
Destination: &withEcode,
|
||||
},
|
||||
}
|
||||
app.Action = func(c *cli.Context) error {
|
||||
return protocAction(c)
|
||||
|
@ -20,16 +20,18 @@ var (
|
||||
withBM bool
|
||||
withGRPC bool
|
||||
withSwagger bool
|
||||
withEcode bool
|
||||
)
|
||||
|
||||
func protocAction(ctx *cli.Context) (err error) {
|
||||
if err = checkProtoc(); err != nil {
|
||||
return err
|
||||
}
|
||||
if !withGRPC && !withBM && !withSwagger {
|
||||
if !withGRPC && !withBM && !withSwagger && !withEcode {
|
||||
withBM = true
|
||||
withGRPC = true
|
||||
withSwagger = true
|
||||
withEcode = true
|
||||
}
|
||||
if withBM {
|
||||
if err = installBMGen(); err != nil {
|
||||
@ -55,6 +57,14 @@ func protocAction(ctx *cli.Context) (err error) {
|
||||
return
|
||||
}
|
||||
}
|
||||
if withEcode {
|
||||
if err = installEcodeGen(); err != nil {
|
||||
return
|
||||
}
|
||||
if err = genEcode(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
log.Printf("generate %v success.\n", ctx.Args())
|
||||
return nil
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
|
||||
const (
|
||||
_getSwaggerGen = "go get -u github.com/bilibili/kratos/tool/protobuf/protoc-gen-bswagger"
|
||||
_swaggerProtoc = "protoc --proto_path=%s --proto_path=%s --proto_path=%s --bswagger_out=explicit_http=true:."
|
||||
_swaggerProtoc = "protoc --proto_path=%s --proto_path=%s --proto_path=%s --bswagger_out=:."
|
||||
)
|
||||
|
||||
func installSwaggerGen() error {
|
||||
|
@ -2,6 +2,7 @@ package naming
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@ -25,6 +26,16 @@ func GetVersionPrefix(pkg string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// GenFileName returns the output name for the generated Go file.
|
||||
func GenFileName(f *descriptor.FileDescriptorProto, suffix string) string {
|
||||
name := *f.Name
|
||||
if ext := path.Ext(name); ext == ".pb" || ext == ".proto" || ext == ".protodevel" {
|
||||
name = name[:len(name)-len(ext)]
|
||||
}
|
||||
name += suffix
|
||||
return name
|
||||
}
|
||||
|
||||
func ServiceName(service *descriptor.ServiceDescriptorProto) string {
|
||||
return utils.CamelCase(service.GetName())
|
||||
}
|
||||
|
@ -44,9 +44,6 @@ func (t *bm) Generate(in *plugin.CodeGeneratorRequest) *plugin.CodeGeneratorResp
|
||||
|
||||
func (t *bm) generateForFile(file *descriptor.FileDescriptorProto) *plugin.CodeGeneratorResponse_File {
|
||||
resp := new(plugin.CodeGeneratorResponse_File)
|
||||
//if len(file.Service) == 0 {
|
||||
// return nil
|
||||
//}
|
||||
|
||||
t.generateFileHeader(file, t.GenPkgName)
|
||||
t.generateImports(file)
|
||||
@ -56,11 +53,8 @@ func (t *bm) generateForFile(file *descriptor.FileDescriptorProto) *plugin.CodeG
|
||||
count += t.generateBMInterface(file, service)
|
||||
t.generateBMRoute(file, service, i)
|
||||
}
|
||||
//if count == 0 {
|
||||
// return nil
|
||||
//}
|
||||
|
||||
resp.Name = proto.String(naming.GoFileName(file, ".bm.go"))
|
||||
resp.Name = proto.String(naming.GenFileName(file, ".bm.go"))
|
||||
resp.Content = proto.String(t.FormattedOutput())
|
||||
t.Output.Reset()
|
||||
|
||||
@ -88,13 +82,13 @@ func (t *bm) generateFileHeader(file *descriptor.FileDescriptorProto, pkgName st
|
||||
t.P("// source: ", file.GetName())
|
||||
t.P()
|
||||
if t.filesHandled == 0 {
|
||||
// doc for the first file
|
||||
t.P("/*")
|
||||
t.P("Package ", t.GenPkgName, " is a generated blademaster stub package.")
|
||||
t.P("This code was generated with kratos/tool/protobuf/protoc-gen-bm ", generator.Version, ".")
|
||||
t.P()
|
||||
comment, err := t.Reg.FileComments(file)
|
||||
if err == nil && comment.Leading != "" {
|
||||
// doc for the first file
|
||||
t.P("/*")
|
||||
t.P("Package ", t.GenPkgName, " is a generated blademaster stub package.")
|
||||
t.P("This code was generated with kratos/tool/protobuf/protoc-gen-bm ", generator.Version, ".")
|
||||
t.P()
|
||||
for _, line := range strings.Split(comment.Leading, "\n") {
|
||||
line = strings.TrimPrefix(line, " ")
|
||||
// ensure we don't escape from the block comment
|
||||
@ -102,12 +96,12 @@ func (t *bm) generateFileHeader(file *descriptor.FileDescriptorProto, pkgName st
|
||||
t.P(line)
|
||||
}
|
||||
t.P()
|
||||
t.P("It is generated from these files:")
|
||||
for _, f := range t.GenFiles {
|
||||
t.P("\t", f.GetName())
|
||||
}
|
||||
t.P("*/")
|
||||
}
|
||||
t.P("It is generated from these files:")
|
||||
for _, f := range t.GenFiles {
|
||||
t.P("\t", f.GetName())
|
||||
}
|
||||
t.P("*/")
|
||||
}
|
||||
t.P(`package `, pkgName)
|
||||
t.P()
|
||||
|
@ -66,7 +66,7 @@ func (t *swaggerGen) generateSwagger(file *descriptor.FileDescriptorProto) *plug
|
||||
t.defsMap = map[string]*typemap.MessageDefinition{}
|
||||
|
||||
out := &plugin.CodeGeneratorResponse_File{}
|
||||
name := naming.GoFileName(file, ".swagger.json")
|
||||
name := naming.GenFileName(file, ".swagger.json")
|
||||
for _, svc := range file.Service {
|
||||
for _, meth := range svc.Method {
|
||||
if !t.ShouldGenForMethod(file, svc, meth) {
|
||||
|
117
tool/protobuf/protoc-gen-ecode/generator/generator.go
Normal file
117
tool/protobuf/protoc-gen-ecode/generator/generator.go
Normal file
@ -0,0 +1,117 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/bilibili/kratos/tool/protobuf/pkg/generator"
|
||||
"github.com/bilibili/kratos/tool/protobuf/pkg/naming"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/golang/protobuf/protoc-gen-go/descriptor"
|
||||
plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
|
||||
)
|
||||
|
||||
type ecode struct {
|
||||
generator.Base
|
||||
filesHandled int
|
||||
}
|
||||
|
||||
// EcodeGenerator ecode generator.
|
||||
func EcodeGenerator() *ecode {
|
||||
t := &ecode{}
|
||||
return t
|
||||
}
|
||||
|
||||
// Generate ...
|
||||
func (t *ecode) Generate(in *plugin.CodeGeneratorRequest) *plugin.CodeGeneratorResponse {
|
||||
t.Setup(in)
|
||||
|
||||
// Showtime! Generate the response.
|
||||
resp := new(plugin.CodeGeneratorResponse)
|
||||
for _, f := range t.GenFiles {
|
||||
respFile := t.generateForFile(f)
|
||||
if respFile != nil {
|
||||
resp.File = append(resp.File, respFile)
|
||||
}
|
||||
}
|
||||
return resp
|
||||
}
|
||||
|
||||
func (t *ecode) generateForFile(file *descriptor.FileDescriptorProto) *plugin.CodeGeneratorResponse_File {
|
||||
var enums []*descriptor.EnumDescriptorProto
|
||||
for _, enum := range file.EnumType {
|
||||
if strings.HasSuffix(*enum.Name, "ErrCode") {
|
||||
enums = append(enums, enum)
|
||||
}
|
||||
}
|
||||
if len(enums) == 0 {
|
||||
return nil
|
||||
}
|
||||
resp := new(plugin.CodeGeneratorResponse_File)
|
||||
t.generateFileHeader(file, t.GenPkgName)
|
||||
t.generateImports(file)
|
||||
for _, enum := range enums {
|
||||
t.generateEcode(file, enum)
|
||||
}
|
||||
|
||||
resp.Name = proto.String(naming.GenFileName(file, ".ecode.go"))
|
||||
resp.Content = proto.String(t.FormattedOutput())
|
||||
t.Output.Reset()
|
||||
|
||||
t.filesHandled++
|
||||
return resp
|
||||
}
|
||||
|
||||
func (t *ecode) generateFileHeader(file *descriptor.FileDescriptorProto, pkgName string) {
|
||||
t.P("// Code generated by protoc-gen-ecode ", generator.Version, ", DO NOT EDIT.")
|
||||
t.P("// source: ", file.GetName())
|
||||
t.P()
|
||||
if t.filesHandled == 0 {
|
||||
comment, err := t.Reg.FileComments(file)
|
||||
if err == nil && comment.Leading != "" {
|
||||
// doc for the first file
|
||||
t.P("/*")
|
||||
t.P("Package ", t.GenPkgName, " is a generated ecode package.")
|
||||
t.P("This code was generated with kratos/tool/protobuf/protoc-gen-ecode ", generator.Version, ".")
|
||||
t.P()
|
||||
for _, line := range strings.Split(comment.Leading, "\n") {
|
||||
line = strings.TrimPrefix(line, " ")
|
||||
// ensure we don't escape from the block comment
|
||||
line = strings.Replace(line, "*/", "* /", -1)
|
||||
t.P(line)
|
||||
}
|
||||
t.P()
|
||||
t.P("It is generated from these files:")
|
||||
for _, f := range t.GenFiles {
|
||||
t.P("\t", f.GetName())
|
||||
}
|
||||
t.P("*/")
|
||||
}
|
||||
}
|
||||
t.P(`package `, pkgName)
|
||||
t.P()
|
||||
}
|
||||
|
||||
func (t *ecode) generateImports(file *descriptor.FileDescriptorProto) {
|
||||
t.P(`import (`)
|
||||
t.P(` "github.com/bilibili/kratos/pkg/ecode"`)
|
||||
t.P(`)`)
|
||||
t.P()
|
||||
t.P(`// to suppressed 'imported but not used warning'`)
|
||||
t.P(`var _ ecode.Codes`)
|
||||
}
|
||||
|
||||
func (t *ecode) generateEcode(file *descriptor.FileDescriptorProto, enum *descriptor.EnumDescriptorProto) {
|
||||
t.P("// ", *enum.Name, " ecode")
|
||||
t.P("var (")
|
||||
|
||||
for _, item := range enum.Value {
|
||||
if *item.Number == 0 {
|
||||
continue
|
||||
}
|
||||
// NOTE: eg: t.P("UserNotExist = New(-404) ")
|
||||
t.P(*item.Name, " = ", "ecode.New(", strconv.Itoa(int(*item.Number)), ")")
|
||||
}
|
||||
|
||||
t.P(")")
|
||||
}
|
27
tool/protobuf/protoc-gen-ecode/generator/generator_test.go
Normal file
27
tool/protobuf/protoc-gen-ecode/generator/generator_test.go
Normal file
@ -0,0 +1,27 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
|
||||
)
|
||||
|
||||
func TestGenerateParseCommandLineParamsError(t *testing.T) {
|
||||
if os.Getenv("BE_CRASHER") == "1" {
|
||||
g := &ecode{}
|
||||
g.Generate(&plugin.CodeGeneratorRequest{
|
||||
Parameter: proto.String("invalid"),
|
||||
})
|
||||
return
|
||||
}
|
||||
cmd := exec.Command(os.Args[0], "-test.run=TestGenerateParseCommandLineParamsError")
|
||||
cmd.Env = append(os.Environ(), "BE_CRASHER=1")
|
||||
err := cmd.Run()
|
||||
if e, ok := err.(*exec.ExitError); ok && !e.Success() {
|
||||
return
|
||||
}
|
||||
t.Fatalf("process ran with err %v, want exit status 1", err)
|
||||
}
|
23
tool/protobuf/protoc-gen-ecode/main.go
Normal file
23
tool/protobuf/protoc-gen-ecode/main.go
Normal file
@ -0,0 +1,23 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/bilibili/kratos/tool/protobuf/pkg/gen"
|
||||
"github.com/bilibili/kratos/tool/protobuf/pkg/generator"
|
||||
ecodegen "github.com/bilibili/kratos/tool/protobuf/protoc-gen-ecode/generator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
versionFlag := flag.Bool("version", false, "print version and exit")
|
||||
flag.Parse()
|
||||
if *versionFlag {
|
||||
fmt.Println(generator.Version)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
g := ecodegen.EcodeGenerator()
|
||||
gen.Main(g)
|
||||
}
|
Loading…
Reference in New Issue
Block a user