gozero template (#147)
* model/rpc generate code from template cache * delete unused(deprecated) code * support template init|update|clean|revert * model: return the execute result for insert and update operation * // deprecated: containsAny * add template test * add default buildVersion * update build version
This commit is contained in:
@@ -32,7 +32,7 @@ func NewDefaultRpcGenerator(ctx *ctx.RpcContext) *defaultRpcGenerator {
|
||||
}
|
||||
|
||||
func (g *defaultRpcGenerator) Generate() (err error) {
|
||||
g.Ctx.Info(aurora.Blue("-> goctl rpc reference documents: ").String() + "「https://github.com/tal-tech/go-zero/blob/master/doc/goctl-rpc.md」")
|
||||
g.Ctx.Info(aurora.Blue("-> goctl rpc reference documents: ").String() + "「https://github.com/tal-tech/zero-doc/blob/main/doc/goctl-rpc.md」")
|
||||
g.Ctx.Warning("-> generating rpc code ...")
|
||||
defer func() {
|
||||
if err == nil {
|
||||
|
||||
@@ -123,7 +123,11 @@ func (g *defaultRpcGenerator) genCall() error {
|
||||
|
||||
filename := filepath.Join(callPath, typesFilename)
|
||||
head := util.GetHead(g.Ctx.ProtoSource)
|
||||
err = util.With("types").GoFmt(true).Parse(callTemplateTypes).SaveTo(map[string]interface{}{
|
||||
text, err := util.LoadTemplate(category, callTypesTemplateFile, callTemplateTypes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = util.With("types").GoFmt(true).Parse(text).SaveTo(map[string]interface{}{
|
||||
"head": head,
|
||||
"const": constLit,
|
||||
"filePackage": service.Name.Lower(),
|
||||
@@ -145,8 +149,11 @@ func (g *defaultRpcGenerator) genCall() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = util.With("shared").GoFmt(true).Parse(callTemplateText).SaveTo(map[string]interface{}{
|
||||
text, err = util.LoadTemplate(category, callTemplateFile, callTemplateText)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = util.With("shared").GoFmt(true).Parse(text).SaveTo(map[string]interface{}{
|
||||
"name": service.Name.Lower(),
|
||||
"head": head,
|
||||
"filePackage": service.Name.Lower(),
|
||||
@@ -166,7 +173,11 @@ func (g *defaultRpcGenerator) genFunction(service *parser.RpcService) ([]string,
|
||||
imports.AddStr(fmt.Sprintf(`%v "%v"`, pkgName, g.mustGetPackage(dirPb)))
|
||||
for _, method := range service.Funcs {
|
||||
imports.AddStr(g.ast.Imports[method.ParameterIn.Package])
|
||||
buffer, err := util.With("sharedFn").Parse(callFunctionTemplate).Execute(map[string]interface{}{
|
||||
text, err := util.LoadTemplate(category, callFunctionTemplateFile, callFunctionTemplate)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
buffer, err := util.With("sharedFn").Parse(text).Execute(map[string]interface{}{
|
||||
"rpcServiceName": service.Name.Title(),
|
||||
"method": method.Name.Title(),
|
||||
"package": pkgName,
|
||||
@@ -189,7 +200,12 @@ func (g *defaultRpcGenerator) getInterfaceFuncs(service *parser.RpcService) ([]s
|
||||
functions := make([]string, 0)
|
||||
|
||||
for _, method := range service.Funcs {
|
||||
buffer, err := util.With("interfaceFn").Parse(callInterfaceFunctionTemplate).Execute(
|
||||
text, err := util.LoadTemplate(category, callInterfaceFunctionTemplateFile, callInterfaceFunctionTemplate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buffer, err := util.With("interfaceFn").Parse(text).Execute(
|
||||
map[string]interface{}{
|
||||
"hasComment": method.HaveDoc(),
|
||||
"comment": method.GetDoc(),
|
||||
|
||||
@@ -23,5 +23,11 @@ func (g *defaultRpcGenerator) genConfig() error {
|
||||
if util.FileExists(fileName) {
|
||||
return nil
|
||||
}
|
||||
return ioutil.WriteFile(fileName, []byte(configTemplate), os.ModePerm)
|
||||
|
||||
text, err := util.LoadTemplate(category, configTemplateFileFile, configTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(fileName, []byte(text), os.ModePerm)
|
||||
}
|
||||
|
||||
@@ -22,7 +22,12 @@ func (g *defaultRpcGenerator) genEtc() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
return util.With("etc").Parse(etcTemplate).SaveTo(map[string]interface{}{
|
||||
text, err := util.LoadTemplate(category, etcTemplateFileFile, etcTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return util.With("etc").Parse(text).SaveTo(map[string]interface{}{
|
||||
"serviceName": g.Ctx.ServiceName.Lower(),
|
||||
}, fileName, false)
|
||||
}
|
||||
|
||||
@@ -61,7 +61,11 @@ func (g *defaultRpcGenerator) genLogic() error {
|
||||
svcImport := fmt.Sprintf(`"%v"`, g.mustGetPackage(dirSvc))
|
||||
imports.AddStr(svcImport)
|
||||
imports.AddStr(importList...)
|
||||
err = util.With("logic").GoFmt(true).Parse(logicTemplate).SaveTo(map[string]interface{}{
|
||||
text, err := util.LoadTemplate(category, logicTemplateFileFile, logicTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = util.With("logic").GoFmt(true).Parse(text).SaveTo(map[string]interface{}{
|
||||
"logicName": fmt.Sprintf("%sLogic", method.Name.Title()),
|
||||
"functions": functions,
|
||||
"imports": strings.Join(imports.KeysStr(), util.NL),
|
||||
@@ -82,7 +86,12 @@ func (g *defaultRpcGenerator) genLogicFunction(packageName string, method *parse
|
||||
}
|
||||
imports.AddStr(g.ast.Imports[method.ParameterIn.Package])
|
||||
imports.AddStr(g.ast.Imports[method.ParameterOut.Package])
|
||||
buffer, err := util.With("fun").Parse(logicFunctionTemplate).Execute(map[string]interface{}{
|
||||
text, err := util.LoadTemplate(category, logicFuncTemplateFileFile, logicFunctionTemplate)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
buffer, err := util.With("fun").Parse(text).Execute(map[string]interface{}{
|
||||
"logicName": fmt.Sprintf("%sLogic", method.Name.Title()),
|
||||
"method": method.Name.Title(),
|
||||
"request": method.ParameterIn.StarExpression,
|
||||
@@ -94,6 +103,7 @@ func (g *defaultRpcGenerator) genLogicFunction(packageName string, method *parse
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
functions = append(functions, buffer.String())
|
||||
return strings.Join(functions, util.NL), imports.KeysStr(), nil
|
||||
}
|
||||
|
||||
@@ -58,7 +58,12 @@ func (g *defaultRpcGenerator) genMain() error {
|
||||
imports = append(imports, configImport, pbImport, remoteImport, svcImport)
|
||||
srv, registers := g.genServer(pkg, file.Service)
|
||||
head := util.GetHead(g.Ctx.ProtoSource)
|
||||
return util.With("main").GoFmt(true).Parse(mainTemplate).SaveTo(map[string]interface{}{
|
||||
text, err := util.LoadTemplate(category, mainTemplateFile, mainTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return util.With("main").GoFmt(true).Parse(text).SaveTo(map[string]interface{}{
|
||||
"head": head,
|
||||
"package": pkg,
|
||||
"serviceName": g.Ctx.ServiceName.Lower(),
|
||||
|
||||
@@ -18,6 +18,7 @@ const (
|
||||
|
||||
func (g *defaultRpcGenerator) genPb() error {
|
||||
pbPath := g.dirM[dirPb]
|
||||
// deprecated: containsAny will be removed in the feature
|
||||
imports, containsAny, err := parser.ParseImport(g.Ctx.ProtoFileSrc)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -59,8 +59,14 @@ func (g *defaultRpcGenerator) genHandler() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
imports.AddStr(importList...)
|
||||
err = util.With("server").GoFmt(true).Parse(serverTemplate).SaveTo(map[string]interface{}{
|
||||
text, err := util.LoadTemplate(category, serverTemplateFile, serverTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = util.With("server").GoFmt(true).Parse(text).SaveTo(map[string]interface{}{
|
||||
"head": head,
|
||||
"types": fmt.Sprintf(typeFmt, service.Name.Title()),
|
||||
"server": service.Name.Title(),
|
||||
@@ -85,7 +91,12 @@ func (g *defaultRpcGenerator) genFunctions(service *parser.RpcService) ([]string
|
||||
}
|
||||
imports.AddStr(g.ast.Imports[method.ParameterIn.Package])
|
||||
imports.AddStr(g.ast.Imports[method.ParameterOut.Package])
|
||||
buffer, err := util.With("func").Parse(functionTemplate).Execute(map[string]interface{}{
|
||||
text, err := util.LoadTemplate(category, serverFuncTemplateFile, functionTemplate)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
buffer, err := util.With("func").Parse(text).Execute(map[string]interface{}{
|
||||
"server": service.Name.Title(),
|
||||
"logicName": fmt.Sprintf("%sLogic", method.Name.Title()),
|
||||
"method": method.Name.Title(),
|
||||
@@ -98,6 +109,7 @@ func (g *defaultRpcGenerator) genFunctions(service *parser.RpcService) ([]string
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
functionList = append(functionList, buffer.String())
|
||||
}
|
||||
return functionList, imports.KeysStr(), nil
|
||||
|
||||
@@ -25,7 +25,12 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
||||
func (g *defaultRpcGenerator) genSvc() error {
|
||||
svcPath := g.dirM[dirSvc]
|
||||
fileName := filepath.Join(svcPath, fileServiceContext)
|
||||
return util.With("svc").GoFmt(true).Parse(svcTemplate).SaveTo(map[string]interface{}{
|
||||
text, err := util.LoadTemplate(category, svcTemplateFile, svcTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return util.With("svc").GoFmt(true).Parse(text).SaveTo(map[string]interface{}{
|
||||
"imports": fmt.Sprintf(`"%v"`, g.mustGetPackage(dirConfig)),
|
||||
}, fileName, false)
|
||||
}
|
||||
|
||||
59
tools/goctl/rpc/gen/rpctemplate.go
Normal file
59
tools/goctl/rpc/gen/rpctemplate.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package gen
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/logrusorgru/aurora"
|
||||
"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/stringx"
|
||||
)
|
||||
|
||||
const rpcTemplateText = `syntax = "proto3";
|
||||
|
||||
package {{.package}};
|
||||
|
||||
message Request {
|
||||
string ping = 1;
|
||||
}
|
||||
|
||||
message Response {
|
||||
string pong = 1;
|
||||
}
|
||||
|
||||
service {{.serviceName}} {
|
||||
rpc Ping(Request) returns(Response);
|
||||
}
|
||||
`
|
||||
|
||||
type rpcTemplate struct {
|
||||
out string
|
||||
console.Console
|
||||
}
|
||||
|
||||
func NewRpcTemplate(out string, idea bool) *rpcTemplate {
|
||||
return &rpcTemplate{
|
||||
out: out,
|
||||
Console: console.NewConsole(idea),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *rpcTemplate) MustGenerate(showState bool) {
|
||||
r.Info(aurora.Blue("-> goctl rpc reference documents: ").String() + "「https://github.com/tal-tech/zero-doc/blob/main/doc/goctl-rpc.md」")
|
||||
r.Info("-> generating template...")
|
||||
protoFilename := filepath.Base(r.out)
|
||||
serviceName := stringx.From(strings.TrimSuffix(protoFilename, filepath.Ext(protoFilename)))
|
||||
text, err := util.LoadTemplate(category, rpcTemplateFile, rpcTemplateText)
|
||||
r.Must(err)
|
||||
|
||||
err = util.With("t").Parse(text).SaveTo(map[string]string{
|
||||
"package": serviceName.UnTitle(),
|
||||
"serviceName": serviceName.Title(),
|
||||
}, r.out, false)
|
||||
r.Must(err)
|
||||
|
||||
if showState {
|
||||
r.Success("Done.")
|
||||
}
|
||||
}
|
||||
@@ -1,54 +1,69 @@
|
||||
package gen
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"fmt"
|
||||
|
||||
"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/stringx"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
const rpcTemplateText = `syntax = "proto3";
|
||||
const (
|
||||
category = "rpc"
|
||||
callTemplateFile = "call.tpl"
|
||||
callTypesTemplateFile = "call-types.tpl"
|
||||
callInterfaceFunctionTemplateFile = "call-interface-func.tpl"
|
||||
callFunctionTemplateFile = "call-func.tpl"
|
||||
configTemplateFileFile = "config.tpl"
|
||||
etcTemplateFileFile = "etc.tpl"
|
||||
logicTemplateFileFile = "logic.tpl"
|
||||
logicFuncTemplateFileFile = "logic-func.tpl"
|
||||
mainTemplateFile = "main.tpl"
|
||||
serverTemplateFile = "server.tpl"
|
||||
serverFuncTemplateFile = "server-func.tpl"
|
||||
svcTemplateFile = "svc.tpl"
|
||||
rpcTemplateFile = "template.tpl"
|
||||
)
|
||||
|
||||
package {{.package}};
|
||||
|
||||
message Request {
|
||||
string ping = 1;
|
||||
var templates = map[string]string{
|
||||
callTemplateFile: callTemplateText,
|
||||
callTypesTemplateFile: callTemplateTypes,
|
||||
callInterfaceFunctionTemplateFile: callInterfaceFunctionTemplate,
|
||||
callFunctionTemplateFile: callFunctionTemplate,
|
||||
configTemplateFileFile: configTemplate,
|
||||
etcTemplateFileFile: etcTemplate,
|
||||
logicTemplateFileFile: logicTemplate,
|
||||
logicFuncTemplateFileFile: logicFunctionTemplate,
|
||||
mainTemplateFile: mainTemplate,
|
||||
serverTemplateFile: serverTemplate,
|
||||
serverFuncTemplateFile: functionTemplate,
|
||||
svcTemplateFile: svcTemplate,
|
||||
rpcTemplateFile: rpcTemplateText,
|
||||
}
|
||||
|
||||
message Response {
|
||||
string pong = 1;
|
||||
func GenTemplates(_ *cli.Context) error {
|
||||
return util.InitTemplates(category, templates)
|
||||
}
|
||||
|
||||
service {{.serviceName}} {
|
||||
rpc Ping(Request) returns(Response);
|
||||
}
|
||||
`
|
||||
|
||||
type rpcTemplate struct {
|
||||
out string
|
||||
console.Console
|
||||
}
|
||||
|
||||
func NewRpcTemplate(out string, idea bool) *rpcTemplate {
|
||||
return &rpcTemplate{
|
||||
out: out,
|
||||
Console: console.NewConsole(idea),
|
||||
func RevertTemplate(name string) error {
|
||||
content, ok := templates[name]
|
||||
if !ok {
|
||||
return fmt.Errorf("%s: no such file name", name)
|
||||
}
|
||||
return util.CreateTemplate(category, name, content)
|
||||
}
|
||||
|
||||
func (r *rpcTemplate) MustGenerate(showState bool) {
|
||||
r.Info("查看rpc生成请移步至「https://github.com/tal-tech/zero-doc/blob/main/doc/goctl-rpc.md」")
|
||||
r.Info("generating template...")
|
||||
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)
|
||||
if showState {
|
||||
r.Success("Done.")
|
||||
}
|
||||
func Clean() error {
|
||||
return util.Clean(category)
|
||||
}
|
||||
|
||||
func Update(category string) error {
|
||||
err := Clean()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return util.InitTemplates(category, templates)
|
||||
}
|
||||
|
||||
func GetCategory() string {
|
||||
return category
|
||||
}
|
||||
|
||||
92
tools/goctl/rpc/gen/template_test.go
Normal file
92
tools/goctl/rpc/gen/template_test.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package gen
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util"
|
||||
)
|
||||
|
||||
func TestGenTemplates(t *testing.T) {
|
||||
err := util.InitTemplates(category, templates)
|
||||
assert.Nil(t, err)
|
||||
dir, err := util.GetTemplateDir(category)
|
||||
assert.Nil(t, err)
|
||||
file := filepath.Join(dir, "main.tpl")
|
||||
data, err := ioutil.ReadFile(file)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, string(data), mainTemplate)
|
||||
}
|
||||
|
||||
func TestRevertTemplate(t *testing.T) {
|
||||
name := "main.tpl"
|
||||
err := util.InitTemplates(category, templates)
|
||||
assert.Nil(t, err)
|
||||
|
||||
dir, err := util.GetTemplateDir(category)
|
||||
assert.Nil(t, err)
|
||||
|
||||
file := filepath.Join(dir, name)
|
||||
data, err := ioutil.ReadFile(file)
|
||||
assert.Nil(t, err)
|
||||
|
||||
modifyData := string(data) + "modify"
|
||||
err = util.CreateTemplate(category, name, modifyData)
|
||||
assert.Nil(t, err)
|
||||
|
||||
data, err = ioutil.ReadFile(file)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, string(data), modifyData)
|
||||
|
||||
assert.Nil(t, RevertTemplate(name))
|
||||
|
||||
data, err = ioutil.ReadFile(file)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, mainTemplate, string(data))
|
||||
}
|
||||
|
||||
func TestClean(t *testing.T) {
|
||||
name := "main.tpl"
|
||||
err := util.InitTemplates(category, templates)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Nil(t, Clean())
|
||||
|
||||
dir, err := util.GetTemplateDir(category)
|
||||
assert.Nil(t, err)
|
||||
|
||||
file := filepath.Join(dir, name)
|
||||
_, err = ioutil.ReadFile(file)
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestUpdate(t *testing.T) {
|
||||
name := "main.tpl"
|
||||
err := util.InitTemplates(category, templates)
|
||||
assert.Nil(t, err)
|
||||
|
||||
dir, err := util.GetTemplateDir(category)
|
||||
assert.Nil(t, err)
|
||||
|
||||
file := filepath.Join(dir, name)
|
||||
data, err := ioutil.ReadFile(file)
|
||||
assert.Nil(t, err)
|
||||
|
||||
modifyData := string(data) + "modify"
|
||||
err = util.CreateTemplate(category, name, modifyData)
|
||||
assert.Nil(t, err)
|
||||
|
||||
data, err = ioutil.ReadFile(file)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, string(data), modifyData)
|
||||
|
||||
assert.Nil(t, Update(category))
|
||||
|
||||
data, err = ioutil.ReadFile(file)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, mainTemplate, string(data))
|
||||
}
|
||||
Reference in New Issue
Block a user