Goctl rpc patch (#117)
* remove mock generation * add: proto project import * update document * remove mock generation * add: proto project import * update document * remove NL * update document * optimize code * add test * add test
This commit is contained in:
@@ -1,68 +1,37 @@
|
||||
package gen
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/dsymonds/gotoc/parser"
|
||||
|
||||
"github.com/tal-tech/go-zero/core/lang"
|
||||
"github.com/tal-tech/go-zero/core/collection"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/rpc/execx"
|
||||
astParser "github.com/tal-tech/go-zero/tools/goctl/rpc/parser"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util/stringx"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/rpc/parser"
|
||||
)
|
||||
|
||||
const (
|
||||
protocCmd = "protoc"
|
||||
grpcPluginCmd = "--go_out=plugins=grpc"
|
||||
)
|
||||
|
||||
func (g *defaultRpcGenerator) genPb() error {
|
||||
importPath, filename := filepath.Split(g.Ctx.ProtoFileSrc)
|
||||
tree, err := parser.ParseFiles([]string{filename}, []string{importPath})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(tree.Files) == 0 {
|
||||
return errors.New("proto ast parse failed")
|
||||
}
|
||||
|
||||
file := tree.Files[0]
|
||||
if len(file.Package) == 0 {
|
||||
return errors.New("expected package, but nothing found")
|
||||
}
|
||||
|
||||
targetStruct := make(map[string]lang.PlaceholderType)
|
||||
for _, item := range file.Messages {
|
||||
if len(item.Messages) > 0 {
|
||||
return fmt.Errorf(`line %v: unexpected inner message near: "%v""`, item.Messages[0].Position.Line, item.Messages[0].Name)
|
||||
}
|
||||
|
||||
name := stringx.From(item.Name)
|
||||
if _, ok := targetStruct[name.Lower()]; ok {
|
||||
return fmt.Errorf("line %v: duplicate %v", item.Position.Line, name)
|
||||
}
|
||||
targetStruct[name.Lower()] = lang.Placeholder
|
||||
}
|
||||
|
||||
pbPath := g.dirM[dirPb]
|
||||
protoFileName := filepath.Base(g.Ctx.ProtoFileSrc)
|
||||
err = g.protocGenGo(pbPath)
|
||||
imports, containsAny, err := parser.ParseImport(g.Ctx.ProtoFileSrc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pbGo := strings.TrimSuffix(protoFileName, ".proto") + ".pb.go"
|
||||
pbFile := filepath.Join(pbPath, pbGo)
|
||||
bts, err := ioutil.ReadFile(pbFile)
|
||||
err = g.protocGenGo(pbPath, imports)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
aspParser := astParser.NewAstParser(bts, targetStruct, g.Ctx.Console)
|
||||
ast, err := aspParser.Parse()
|
||||
ast, err := parser.Transfer(g.Ctx.ProtoFileSrc, pbPath, imports, g.Ctx.Console)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ast.ContainsAny = containsAny
|
||||
|
||||
if len(ast.Service) == 0 {
|
||||
return fmt.Errorf("service not found")
|
||||
@@ -71,10 +40,35 @@ func (g *defaultRpcGenerator) genPb() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *defaultRpcGenerator) protocGenGo(target string) error {
|
||||
src := filepath.Dir(g.Ctx.ProtoFileSrc)
|
||||
sh := fmt.Sprintf(`protoc -I=%s --go_out=plugins=grpc:%s %s`, src, target, g.Ctx.ProtoFileSrc)
|
||||
stdout, err := execx.Run(sh, "")
|
||||
func (g *defaultRpcGenerator) protocGenGo(target string, imports []*parser.Import) error {
|
||||
dir := filepath.Dir(g.Ctx.ProtoFileSrc)
|
||||
// cmd join,see the document of proto generating class @https://developers.google.com/protocol-buffers/docs/proto3#generating
|
||||
// template: protoc -I=${import_path} -I=${other_import_path} -I=${...} --go_out=plugins=grpc,M${pb_package_kv}, M${...} :${target_dir}
|
||||
// eg: protoc -I=${GOPATH}/src -I=. example.proto --go_out=plugins=grpc,Mbase/base.proto=github.com/go-zero/base.proto:.
|
||||
// note: the external import out of the project which are found in ${GOPATH}/src so far.
|
||||
|
||||
buffer := new(bytes.Buffer)
|
||||
buffer.WriteString(protocCmd + " ")
|
||||
targetImportFiltered := collection.NewSet()
|
||||
|
||||
for _, item := range imports {
|
||||
buffer.WriteString(fmt.Sprintf("-I=%s ", item.OriginalDir))
|
||||
if len(item.BridgeImport) == 0 {
|
||||
continue
|
||||
}
|
||||
targetImportFiltered.AddStr(item.BridgeImport)
|
||||
|
||||
}
|
||||
buffer.WriteString("-I=${GOPATH}/src ")
|
||||
buffer.WriteString(fmt.Sprintf("-I=%s %s ", dir, g.Ctx.ProtoFileSrc))
|
||||
|
||||
buffer.WriteString(grpcPluginCmd)
|
||||
if targetImportFiltered.Count() > 0 {
|
||||
buffer.WriteString(fmt.Sprintf(",%v", strings.Join(targetImportFiltered.KeysStr(), ",")))
|
||||
}
|
||||
buffer.WriteString(":" + target)
|
||||
g.Ctx.Debug("-> " + buffer.String())
|
||||
stdout, err := execx.Run(buffer.String(), "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user