quickly generating rpc demo service (#60)
* add execute files * add protoc-osx * add rpc generation * add rpc generation * add: rpc template generation * add README.md * format error * reactor templatex.go * update project.go & README.md * add: quickly generate rpc service
This commit is contained in:
@@ -4,6 +4,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
|
||||||
"github.com/tal-tech/go-zero/core/logx"
|
"github.com/tal-tech/go-zero/core/logx"
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/api/apigen"
|
"github.com/tal-tech/go-zero/tools/goctl/api/apigen"
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/api/dartgen"
|
"github.com/tal-tech/go-zero/tools/goctl/api/dartgen"
|
||||||
@@ -19,7 +21,6 @@ import (
|
|||||||
"github.com/tal-tech/go-zero/tools/goctl/feature"
|
"github.com/tal-tech/go-zero/tools/goctl/feature"
|
||||||
model "github.com/tal-tech/go-zero/tools/goctl/model/sql/command"
|
model "github.com/tal-tech/go-zero/tools/goctl/model/sql/command"
|
||||||
rpc "github.com/tal-tech/go-zero/tools/goctl/rpc/command"
|
rpc "github.com/tal-tech/go-zero/tools/goctl/rpc/command"
|
||||||
"github.com/urfave/cli"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -193,6 +194,17 @@ var (
|
|||||||
Name: "rpc",
|
Name: "rpc",
|
||||||
Usage: "generate rpc code",
|
Usage: "generate rpc code",
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []cli.Command{
|
||||||
|
{
|
||||||
|
Name: "new",
|
||||||
|
Usage: `generate rpc demo service`,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "idea",
|
||||||
|
Usage: "whether the command execution environment is from idea plugin. [option]",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: rpc.RpcNew,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "template",
|
Name: "template",
|
||||||
Usage: `generate proto template`,
|
Usage: `generate proto template`,
|
||||||
@@ -224,10 +236,6 @@ var (
|
|||||||
Name: "service, srv",
|
Name: "service, srv",
|
||||||
Usage: `the name of rpc service. [option]`,
|
Usage: `the name of rpc service. [option]`,
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
|
||||||
Name: "shared",
|
|
||||||
Usage: `the dir of the shared file,default path is "${pwd}/shared. [option]`,
|
|
||||||
},
|
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "idea",
|
Name: "idea",
|
||||||
Usage: "whether the command execution environment is from idea plugin. [option]",
|
Usage: "whether the command execution environment is from idea plugin. [option]",
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
# Change log
|
# Change log
|
||||||
|
|
||||||
|
# 2020-08-29
|
||||||
|
* rpc greet服务一键生成
|
||||||
|
* 修复相对路径生成rpc服务package引入错误bug
|
||||||
|
* 移除`--shared`参数
|
||||||
|
|
||||||
# 2020-08-29
|
# 2020-08-29
|
||||||
* 新增支持windows生成
|
* 新增支持windows生成
|
||||||
|
|
||||||
|
|||||||
@@ -8,74 +8,118 @@ Goctl Rpc是`goctl`脚手架下的一个rpc服务代码生成模块,支持prot
|
|||||||
|
|
||||||
# 快速开始
|
# 快速开始
|
||||||
|
|
||||||
### 生成proto模板
|
### 方式一:快速生成greet服务
|
||||||
|
|
||||||
```shell script
|
通过命令 `goctl rpc new ${servieName}`生成
|
||||||
$ goctl rpc template -o=user.proto
|
|
||||||
```
|
|
||||||
|
|
||||||
```golang
|
如生成greet rpc服务:
|
||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
package remote;
|
```shell script
|
||||||
|
$ goctl rpc new greet
|
||||||
|
```
|
||||||
|
|
||||||
message Request {
|
执行后代码结构如下:
|
||||||
// 用户名
|
|
||||||
string username = 1;
|
|
||||||
// 用户密码
|
|
||||||
string password = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Response {
|
```golang
|
||||||
// 用户名称
|
└── greet
|
||||||
string name = 1;
|
|
||||||
// 用户性别
|
|
||||||
string gender = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
service User {
|
|
||||||
// 登录
|
|
||||||
rpc Login(Request)returns(Response);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
### 生成rpc服务代码
|
|
||||||
|
|
||||||
生成user rpc服务
|
|
||||||
```
|
|
||||||
$ goctl rpc proto -src=user.proto
|
|
||||||
```
|
|
||||||
|
|
||||||
代码tree
|
|
||||||
|
|
||||||
```
|
|
||||||
user
|
|
||||||
├── etc
|
├── etc
|
||||||
│ └── user.json
|
│ └── greet.yaml
|
||||||
|
├── go.mod
|
||||||
|
├── go.sum
|
||||||
|
├── greet
|
||||||
|
│ ├── greet.go
|
||||||
|
│ ├── greet_mock.go
|
||||||
|
│ └── types.go
|
||||||
|
├── greet.go
|
||||||
|
├── greet.proto
|
||||||
├── internal
|
├── internal
|
||||||
│ ├── config
|
│ ├── config
|
||||||
│ │ └── config.go
|
│ │ └── config.go
|
||||||
│ ├── handler
|
|
||||||
│ │ ├── loginhandler.go
|
|
||||||
│ ├── logic
|
│ ├── logic
|
||||||
│ │ └── loginlogic.go
|
│ │ └── pinglogic.go
|
||||||
|
│ ├── server
|
||||||
|
│ │ └── greetserver.go
|
||||||
│ └── svc
|
│ └── svc
|
||||||
│ └── servicecontext.go
|
│ └── servicecontext.go
|
||||||
├── pb
|
└── pb
|
||||||
│ └── user.pb.go
|
└── greet.pb.go
|
||||||
├── shared
|
```
|
||||||
│ ├── mockusermodel.go
|
|
||||||
│ ├── types.go
|
|
||||||
│ └── usermodel.go
|
|
||||||
├── user.go
|
|
||||||
└── user.proto
|
|
||||||
|
|
||||||
```
|
rpc一键生成常见问题解决见 <a href="#常见问题解决">常见问题解决</a>
|
||||||
|
### 方式二:通过指定proto生成rpc服务
|
||||||
|
|
||||||
|
* 生成proto模板
|
||||||
|
|
||||||
|
```shell script
|
||||||
|
$ goctl rpc template -o=user.proto
|
||||||
|
```
|
||||||
|
|
||||||
|
```golang
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package remote;
|
||||||
|
|
||||||
|
message Request {
|
||||||
|
// 用户名
|
||||||
|
string username = 1;
|
||||||
|
// 用户密码
|
||||||
|
string password = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Response {
|
||||||
|
// 用户名称
|
||||||
|
string name = 1;
|
||||||
|
// 用户性别
|
||||||
|
string gender = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
service User {
|
||||||
|
// 登录
|
||||||
|
rpc Login(Request)returns(Response);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
* 生成rpc服务代码
|
||||||
|
|
||||||
|
```
|
||||||
|
$ goctl rpc proto -src=user.proto
|
||||||
|
```
|
||||||
|
|
||||||
|
代码tree
|
||||||
|
|
||||||
|
```
|
||||||
|
user
|
||||||
|
├── etc
|
||||||
|
│ └── user.json
|
||||||
|
├── internal
|
||||||
|
│ ├── config
|
||||||
|
│ │ └── config.go
|
||||||
|
│ ├── handler
|
||||||
|
│ │ ├── loginhandler.go
|
||||||
|
│ ├── logic
|
||||||
|
│ │ └── loginlogic.go
|
||||||
|
│ └── svc
|
||||||
|
│ └── servicecontext.go
|
||||||
|
├── pb
|
||||||
|
│ └── user.pb.go
|
||||||
|
├── shared
|
||||||
|
│ ├── mockusermodel.go
|
||||||
|
│ ├── types.go
|
||||||
|
│ └── usermodel.go
|
||||||
|
├── user.go
|
||||||
|
└── user.proto
|
||||||
|
|
||||||
|
```
|
||||||
# 准备工作
|
# 准备工作
|
||||||
|
|
||||||
* 安装了go环境
|
* 安装了go环境
|
||||||
* 安装了protoc&protoc-gen-go,并且已经设置环境变量
|
* 安装了protoc&protoc-gen-go,并且已经设置环境变量
|
||||||
* mockgen(可选)
|
* mockgen(可选,将移除)
|
||||||
|
* 更多问题请见 <a href="#注意事项">注意事项</a>
|
||||||
|
|
||||||
# 用法
|
# 用法
|
||||||
|
|
||||||
|
### rpc服务生成用法
|
||||||
|
|
||||||
```shell script
|
```shell script
|
||||||
$ goctl rpc proto -h
|
$ goctl rpc proto -h
|
||||||
```
|
```
|
||||||
@@ -91,27 +135,28 @@ OPTIONS:
|
|||||||
--src value, -s value the file path of the proto source file
|
--src value, -s value the file path of the proto source file
|
||||||
--dir value, -d value the target path of the code,default path is "${pwd}". [option]
|
--dir value, -d value the target path of the code,default path is "${pwd}". [option]
|
||||||
--service value, --srv value the name of rpc service. [option]
|
--service value, --srv value the name of rpc service. [option]
|
||||||
--shared value the dir of the shared file,default path is "${pwd}/shared. [option]"
|
--shared[已废弃] value the dir of the shared file,default path is "${pwd}/shared. [option]"
|
||||||
--idea whether the command execution environment is from idea plugin. [option]
|
--idea whether the command execution environment is from idea plugin. [option]
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
* 参数说明
|
### 参数说明
|
||||||
* --src 必填,proto数据源,目前暂时支持单个proto文件生成,这里不支持(不建议)外部依赖
|
|
||||||
* --dir 非必填,默认为proto文件所在目录,生成代码的目标目录
|
* --src 必填,proto数据源,目前暂时支持单个proto文件生成,这里不支持(不建议)外部依赖
|
||||||
* --service 服务名称,非必填,默认为proto文件所在目录名称,但是,如果proto所在目录为一下结构:
|
* --dir 非必填,默认为proto文件所在目录,生成代码的目标目录
|
||||||
```shell script
|
* --service 服务名称,非必填,默认为proto文件所在目录名称,但是,如果proto所在目录为一下结构:
|
||||||
user
|
```shell script
|
||||||
├── cmd
|
user
|
||||||
│ └── rpc
|
├── cmd
|
||||||
│ └── user.proto
|
│ └── rpc
|
||||||
```
|
│ └── user.proto
|
||||||
则服务名称亦为user,而非proto所在文件夹名称了,这里推荐使用这种结构,可以方便在同一个服务名下建立不同类型的服务(api、rpc、mq等),便于代码管理与维护。
|
```
|
||||||
* --shared 非必填,默认为$dir(xxx.proto)/shared,rpc client逻辑代码存放目录。
|
则服务名称亦为user,而非proto所在文件夹名称了,这里推荐使用这种结构,可以方便在同一个服务名下建立不同类型的服务(api、rpc、mq等),便于代码管理与维护。
|
||||||
|
* --shared[⚠️已废弃] 非必填,默认为$dir(xxx.proto)/shared,rpc client逻辑代码存放目录。
|
||||||
> 注意:这里的shared文件夹名称将会是代码中的package名称。
|
|
||||||
|
> 注意:这里的shared文件夹名称将会是代码中的package名称。
|
||||||
* --idea 非必填,是否为idea插件中执行,保留字段,终端执行可以忽略
|
|
||||||
|
* --idea 非必填,是否为idea插件中执行,保留字段,终端执行可以忽略
|
||||||
|
|
||||||
# 开发人员需要做什么
|
# 开发人员需要做什么
|
||||||
|
|
||||||
@@ -124,6 +169,10 @@ OPTIONS:
|
|||||||
对于需要进行rpc mock的开发人员,在安装了`mockgen`工具的前提下可以在rpc的shared文件中生成好对应的mock文件。
|
对于需要进行rpc mock的开发人员,在安装了`mockgen`工具的前提下可以在rpc的shared文件中生成好对应的mock文件。
|
||||||
|
|
||||||
# 注意事项
|
# 注意事项
|
||||||
|
* `google.golang.org/grpc`需要降级到v1.26.0,且protoc-gen-go版本不能高于v1.3.2(see [https://github.com/grpc/grpc-go/issues/3347](https://github.com/grpc/grpc-go/issues/3347))即
|
||||||
|
```
|
||||||
|
replace google.golang.org/grpc => google.golang.org/grpc v1.26.0
|
||||||
|
```
|
||||||
* proto不支持暂多文件同时生成
|
* proto不支持暂多文件同时生成
|
||||||
* proto不支持外部依赖包引入,message不支持inline
|
* proto不支持外部依赖包引入,message不支持inline
|
||||||
* 目前main文件、shared文件、handler文件会被强制覆盖,而和开发人员手动需要编写的则不会覆盖生成,这一类在代码头部均有
|
* 目前main文件、shared文件、handler文件会被强制覆盖,而和开发人员手动需要编写的则不会覆盖生成,这一类在代码头部均有
|
||||||
@@ -133,8 +182,42 @@ OPTIONS:
|
|||||||
```
|
```
|
||||||
的标识,请注意不要将也写业务性代码写在里面。
|
的标识,请注意不要将也写业务性代码写在里面。
|
||||||
|
|
||||||
|
# 常见问题解决(go mod工程)
|
||||||
|
|
||||||
|
* 错误一:
|
||||||
|
|
||||||
|
```golang
|
||||||
|
pb/xx.pb.go:220:7: undefined: grpc.ClientConnInterface
|
||||||
|
pb/xx.pb.go:224:11: undefined: grpc.SupportPackageIsVersion6
|
||||||
|
pb/xx.pb.go:234:5: undefined: grpc.ClientConnInterface
|
||||||
|
pb/xx.pb.go:237:24: undefined: grpc.ClientConnInterface
|
||||||
|
```
|
||||||
|
解决方法:请将`protoc-gen-go`版本降至v1.3.2及一下
|
||||||
|
|
||||||
|
* 错误二:
|
||||||
|
|
||||||
|
```golang
|
||||||
|
|
||||||
|
# go.etcd.io/etcd/clientv3/balancer/picker
|
||||||
|
../../../go/pkg/mod/go.etcd.io/etcd@v0.0.0-20200402134248-51bdeb39e698/clientv3/balancer/picker/err.go:25:9: cannot use &errPicker literal (type *errPicker) as type Picker in return argument:*errPicker does not implement Picker (wrong type for Pick method)
|
||||||
|
have Pick(context.Context, balancer.PickInfo) (balancer.SubConn, func(balancer.DoneInfo), error)
|
||||||
|
want Pick(balancer.PickInfo) (balancer.PickResult, error)
|
||||||
|
../../../go/pkg/mod/go.etcd.io/etcd@v0.0.0-20200402134248-51bdeb39e698/clientv3/balancer/picker/roundrobin_balanced.go:33:9: cannot use &rrBalanced literal (type *rrBalanced) as type Picker in return argument:
|
||||||
|
*rrBalanced does not implement Picker (wrong type for Pick method)
|
||||||
|
have Pick(context.Context, balancer.PickInfo) (balancer.SubConn, func(balancer.DoneInfo), error)
|
||||||
|
want Pick(balancer.PickInfo) (balancer.PickResult, error)
|
||||||
|
#github.com/tal-tech/go-zero/rpcx/internal/balancer/p2c
|
||||||
|
../../../go/pkg/mod/github.com/tal-tech/go-zero@v1.0.12/rpcx/internal/balancer/p2c/p2c.go:41:32: not enough arguments in call to base.NewBalancerBuilder
|
||||||
|
have (string, *p2cPickerBuilder)
|
||||||
|
want (string, base.PickerBuilder, base.Config)
|
||||||
|
../../../go/pkg/mod/github.com/tal-tech/go-zero@v1.0.12/rpcx/internal/balancer/p2c/p2c.go:58:9: cannot use &p2cPicker literal (type *p2cPicker) as type balancer.Picker in return argument:
|
||||||
|
*p2cPicker does not implement balancer.Picker (wrong type for Pick method)
|
||||||
|
have Pick(context.Context, balancer.PickInfo) (balancer.SubConn, func(balancer.DoneInfo), error)
|
||||||
|
want Pick(balancer.PickInfo) (balancer.PickResult, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
解决方法:
|
||||||
|
|
||||||
|
```golang
|
||||||
|
replace google.golang.org/grpc => google.golang.org/grpc v1.26.0
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/rpc/ctx"
|
"github.com/tal-tech/go-zero/tools/goctl/rpc/ctx"
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/rpc/gen"
|
"github.com/tal-tech/go-zero/tools/goctl/rpc/gen"
|
||||||
"github.com/urfave/cli"
|
"github.com/tal-tech/go-zero/tools/goctl/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Rpc(c *cli.Context) error {
|
func Rpc(c *cli.Context) error {
|
||||||
@@ -17,6 +23,39 @@ func RpcTemplate(c *cli.Context) error {
|
|||||||
out := c.String("out")
|
out := c.String("out")
|
||||||
idea := c.Bool("idea")
|
idea := c.Bool("idea")
|
||||||
generator := gen.NewRpcTemplate(out, idea)
|
generator := gen.NewRpcTemplate(out, idea)
|
||||||
generator.MustGenerate()
|
generator.MustGenerate(true)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func RpcNew(c *cli.Context) error {
|
||||||
|
idea := c.Bool("idea")
|
||||||
|
arg := c.Args().First()
|
||||||
|
if len(arg) == 0 {
|
||||||
|
arg = "greet"
|
||||||
|
}
|
||||||
|
abs, err := filepath.Abs(arg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = os.Stat(abs)
|
||||||
|
if err != nil {
|
||||||
|
if !os.IsNotExist(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = util.MkdirIfNotExist(abs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dir := filepath.Base(filepath.Clean(abs))
|
||||||
|
|
||||||
|
protoSrc := filepath.Join(abs, fmt.Sprintf("%v.proto", dir))
|
||||||
|
templateGenerator := gen.NewRpcTemplate(protoSrc, idea)
|
||||||
|
templateGenerator.MustGenerate(false)
|
||||||
|
|
||||||
|
rpcCtx := ctx.MustCreateRpcContext(protoSrc, "", "", idea)
|
||||||
|
generator := gen.NewDefaultRpcGenerator(rpcCtx)
|
||||||
|
rpcCtx.Must(generator.Generate())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,13 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
|
||||||
"github.com/tal-tech/go-zero/core/logx"
|
"github.com/tal-tech/go-zero/core/logx"
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/util"
|
"github.com/tal-tech/go-zero/tools/goctl/util"
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/util/console"
|
"github.com/tal-tech/go-zero/tools/goctl/util/console"
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/util/project"
|
"github.com/tal-tech/go-zero/tools/goctl/util/project"
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/util/stringx"
|
"github.com/tal-tech/go-zero/tools/goctl/util/stringx"
|
||||||
"github.com/urfave/cli"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -30,13 +31,12 @@ type RpcContext struct {
|
|||||||
ProtoFileSrc string
|
ProtoFileSrc string
|
||||||
ProtoSource string
|
ProtoSource string
|
||||||
TargetDir string
|
TargetDir string
|
||||||
|
IsInGoEnv bool
|
||||||
console.Console
|
console.Console
|
||||||
}
|
}
|
||||||
|
|
||||||
func MustCreateRpcContext(protoSrc, targetDir, serviceName string, idea bool) *RpcContext {
|
func MustCreateRpcContext(protoSrc, targetDir, serviceName string, idea bool) *RpcContext {
|
||||||
log := console.NewConsole(idea)
|
log := console.NewConsole(idea)
|
||||||
info, err := project.Prepare(targetDir, true)
|
|
||||||
log.Must(err)
|
|
||||||
|
|
||||||
if stringx.From(protoSrc).IsEmptyOrSpace() {
|
if stringx.From(protoSrc).IsEmptyOrSpace() {
|
||||||
log.Fatalln("expected proto source, but nothing found")
|
log.Fatalln("expected proto source, but nothing found")
|
||||||
@@ -62,6 +62,9 @@ func MustCreateRpcContext(protoSrc, targetDir, serviceName string, idea bool) *R
|
|||||||
log.Fatalln("service name is not found")
|
log.Fatalln("service name is not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info, err := project.Prepare(targetDir, true)
|
||||||
|
log.Must(err)
|
||||||
|
|
||||||
return &RpcContext{
|
return &RpcContext{
|
||||||
ProjectPath: info.Path,
|
ProjectPath: info.Path,
|
||||||
ProjectName: stringx.From(info.Name),
|
ProjectName: stringx.From(info.Name),
|
||||||
@@ -71,6 +74,7 @@ func MustCreateRpcContext(protoSrc, targetDir, serviceName string, idea bool) *R
|
|||||||
ProtoFileSrc: srcFp,
|
ProtoFileSrc: srcFp,
|
||||||
ProtoSource: filepath.Base(srcFp),
|
ProtoSource: filepath.Base(srcFp),
|
||||||
TargetDir: targetDirFp,
|
TargetDir: targetDirFp,
|
||||||
|
IsInGoEnv: info.IsInGoEnv,
|
||||||
Console: log,
|
Console: log,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,11 @@ func (g *defaultRpcGenerator) Generate() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = g.initGoMod()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
err = g.genEtc()
|
err = g.genEtc()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@@ -82,5 +87,5 @@ func (g *defaultRpcGenerator) Generate() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,10 +113,7 @@ func (g *defaultRpcGenerator) genCall() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
service := file.Service[0]
|
service := file.Service[0]
|
||||||
callPath, err := filepath.Abs(service.Name.Lower())
|
callPath := filepath.Join(g.dirM[dirTarget], service.Name.Lower())
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = util.MkdirIfNotExist(callPath); err != nil {
|
if err = util.MkdirIfNotExist(callPath); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -152,7 +149,7 @@ func (g *defaultRpcGenerator) genCall() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mockFile := filepath.Join(callPath, fmt.Sprintf("%s_mock.go", service.Name.Lower()))
|
mockFile := filepath.Join(callPath, fmt.Sprintf("%s_mock.go", service.Name.Lower()))
|
||||||
os.Remove(mockFile)
|
_ = os.Remove(mockFile)
|
||||||
err = util.With("shared").GoFmt(true).Parse(callTemplateText).SaveTo(map[string]interface{}{
|
err = util.With("shared").GoFmt(true).Parse(callTemplateText).SaveTo(map[string]interface{}{
|
||||||
"name": service.Name.Lower(),
|
"name": service.Name.Lower(),
|
||||||
"head": head,
|
"head": head,
|
||||||
@@ -167,9 +164,9 @@ func (g *defaultRpcGenerator) genCall() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// if mockgen is already installed, it will generate code of gomock for shared files
|
// if mockgen is already installed, it will generate code of gomock for shared files
|
||||||
_, err = exec.LookPath("mockgen")
|
// Deprecated: it will be removed
|
||||||
if mockGenInstalled {
|
if mockGenInstalled && g.Ctx.IsInGoEnv {
|
||||||
execx.Run(fmt.Sprintf("go generate %s", filename), "")
|
_, _ = execx.Run(fmt.Sprintf("go generate %s", filename), "")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
22
tools/goctl/rpc/gen/gomod.go
Normal file
22
tools/goctl/rpc/gen/gomod.go
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package gen
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/tal-tech/go-zero/core/logx"
|
||||||
|
"github.com/tal-tech/go-zero/tools/goctl/rpc/execx"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (g *defaultRpcGenerator) initGoMod() error {
|
||||||
|
if !g.Ctx.IsInGoEnv {
|
||||||
|
projectDir := g.dirM[dirTarget]
|
||||||
|
cmd := fmt.Sprintf("go mod init %s", g.Ctx.ProjectName.Source())
|
||||||
|
output, err := execx.Run(fmt.Sprintf(cmd), projectDir)
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
g.Ctx.Info(output)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -1,26 +1,28 @@
|
|||||||
package gen
|
package gen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/util"
|
"github.com/tal-tech/go-zero/tools/goctl/util"
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/util/console"
|
"github.com/tal-tech/go-zero/tools/goctl/util/console"
|
||||||
|
"github.com/tal-tech/go-zero/tools/goctl/util/stringx"
|
||||||
)
|
)
|
||||||
|
|
||||||
const rpcTemplateText = `syntax = "proto3";
|
const rpcTemplateText = `syntax = "proto3";
|
||||||
|
|
||||||
package remote;
|
package {{.package}};
|
||||||
|
|
||||||
message Request {
|
message Request {
|
||||||
string username = 1;
|
string ping = 1;
|
||||||
string password = 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message Response {
|
message Response {
|
||||||
string name = 1;
|
string pong = 1;
|
||||||
string gender = 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
service User {
|
service {{.serviceName}} {
|
||||||
rpc Login(Request) returns(Response);
|
rpc Ping(Request) returns(Response);
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
@@ -36,8 +38,15 @@ func NewRpcTemplate(out string, idea bool) *rpcTemplate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *rpcTemplate) MustGenerate() {
|
func (r *rpcTemplate) MustGenerate(showState bool) {
|
||||||
err := util.With("t").Parse(rpcTemplateText).SaveTo(nil, r.out, false)
|
protoFilename := filepath.Base(r.out)
|
||||||
|
serviceName := stringx.From(strings.TrimSuffix(protoFilename, filepath.Ext(protoFilename)))
|
||||||
|
err := util.With("t").Parse(rpcTemplateText).SaveTo(map[string]string{
|
||||||
|
"package": serviceName.UnTitle(),
|
||||||
|
"serviceName": serviceName.Title(),
|
||||||
|
}, r.out, false)
|
||||||
r.Must(err)
|
r.Must(err)
|
||||||
r.Success("Done.")
|
if showState {
|
||||||
|
r.Success("Done.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ type (
|
|||||||
Path string // Project path name
|
Path string // Project path name
|
||||||
Name string // Project name
|
Name string // Project name
|
||||||
Package string // The service related package
|
Package string // The service related package
|
||||||
GoMod GoMod
|
// true-> project in go path or project init with go mod,or else->false
|
||||||
|
IsInGoEnv bool
|
||||||
|
GoMod GoMod
|
||||||
}
|
}
|
||||||
|
|
||||||
GoMod struct {
|
GoMod struct {
|
||||||
@@ -75,6 +77,7 @@ func Prepare(projectDir string, checkGrpcEnv bool) (*Project, error) {
|
|||||||
|
|
||||||
goPath = strings.TrimSpace(ret)
|
goPath = strings.TrimSpace(ret)
|
||||||
src := filepath.Join(goPath, "src")
|
src := filepath.Join(goPath, "src")
|
||||||
|
var isInGoEnv = true
|
||||||
if len(goMod) > 0 {
|
if len(goMod) > 0 {
|
||||||
path = filepath.Dir(goMod)
|
path = filepath.Dir(goMod)
|
||||||
name = filepath.Base(path)
|
name = filepath.Base(path)
|
||||||
@@ -103,6 +106,7 @@ func Prepare(projectDir string, checkGrpcEnv bool) (*Project, error) {
|
|||||||
name = filepath.Clean(filepath.Base(absPath))
|
name = filepath.Clean(filepath.Base(absPath))
|
||||||
path = projectDir
|
path = projectDir
|
||||||
pkg = name
|
pkg = name
|
||||||
|
isInGoEnv = false
|
||||||
} else {
|
} else {
|
||||||
r := strings.TrimPrefix(pwd, src+string(filepath.Separator))
|
r := strings.TrimPrefix(pwd, src+string(filepath.Separator))
|
||||||
name = filepath.Dir(r)
|
name = filepath.Dir(r)
|
||||||
@@ -116,9 +120,10 @@ func Prepare(projectDir string, checkGrpcEnv bool) (*Project, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &Project{
|
return &Project{
|
||||||
Name: name,
|
Name: name,
|
||||||
Path: path,
|
Path: path,
|
||||||
Package: pkg,
|
Package: pkg,
|
||||||
|
IsInGoEnv: isInGoEnv,
|
||||||
GoMod: GoMod{
|
GoMod: GoMod{
|
||||||
Module: module,
|
Module: module,
|
||||||
Path: goMod,
|
Path: goMod,
|
||||||
|
|||||||
Reference in New Issue
Block a user