patch model&rpc (#207)
* change column to read from information_schema * reactor generate mode from datasource * reactor generate mode from datasource * add primary key check logic * resolve rebase conflicts * add naming style * add filename test case * resolve rebase conflicts * reactor test * add test case * change shell script to makefile * update rpc new * update gen_test.go * format code * format code * update test * generates alias
This commit is contained in:
@@ -5,7 +5,6 @@ import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/tal-tech/go-zero/tools/goctl/rpc/execx"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/rpc/generator"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
@@ -16,6 +15,7 @@ import (
|
||||
func Rpc(c *cli.Context) error {
|
||||
src := c.String("src")
|
||||
out := c.String("dir")
|
||||
style := c.String("style")
|
||||
protoImportPath := c.StringSlice("proto_path")
|
||||
if len(src) == 0 {
|
||||
return errors.New("missing -src")
|
||||
@@ -23,7 +23,13 @@ func Rpc(c *cli.Context) error {
|
||||
if len(out) == 0 {
|
||||
return errors.New("missing -dir")
|
||||
}
|
||||
g := generator.NewDefaultRpcGenerator()
|
||||
|
||||
namingStyle, valid := generator.IsNamingValid(style)
|
||||
if !valid {
|
||||
return fmt.Errorf("unexpected naming style %s", style)
|
||||
}
|
||||
|
||||
g := generator.NewDefaultRpcGenerator(namingStyle)
|
||||
return g.Generate(src, out, protoImportPath)
|
||||
}
|
||||
|
||||
@@ -36,6 +42,12 @@ func RpcNew(c *cli.Context) error {
|
||||
return fmt.Errorf("unexpected ext: %s", ext)
|
||||
}
|
||||
|
||||
style := c.String("style")
|
||||
namingStyle, valid := generator.IsNamingValid(style)
|
||||
if !valid {
|
||||
return fmt.Errorf("expected naming style [lower|camel|snake], but found %s", style)
|
||||
}
|
||||
|
||||
protoName := name + ".proto"
|
||||
filename := filepath.Join(".", name, protoName)
|
||||
src, err := filepath.Abs(filename)
|
||||
@@ -48,13 +60,7 @@ func RpcNew(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
workDir := filepath.Dir(src)
|
||||
_, err = execx.Run("go mod init "+name, workDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
g := generator.NewDefaultRpcGenerator()
|
||||
g := generator.NewDefaultRpcGenerator(namingStyle)
|
||||
return g.Generate(src, filepath.Dir(src), nil)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: common.proto
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type User struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *User) Reset() { *m = User{} }
|
||||
func (m *User) String() string { return proto.CompactTextString(m) }
|
||||
func (*User) ProtoMessage() {}
|
||||
func (*User) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_555bd8c177793206, []int{0}
|
||||
}
|
||||
|
||||
func (m *User) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_User.Unmarshal(m, b)
|
||||
}
|
||||
func (m *User) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_User.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *User) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_User.Merge(m, src)
|
||||
}
|
||||
func (m *User) XXX_Size() int {
|
||||
return xxx_messageInfo_User.Size(m)
|
||||
}
|
||||
func (m *User) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_User.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_User proto.InternalMessageInfo
|
||||
|
||||
func (m *User) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*User)(nil), "common.User")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("common.proto", fileDescriptor_555bd8c177793206) }
|
||||
|
||||
var fileDescriptor_555bd8c177793206 = []byte{
|
||||
// 72 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xcf, 0xcd,
|
||||
0xcd, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x83, 0xf0, 0x94, 0xa4, 0xb8, 0x58,
|
||||
0x42, 0x8b, 0x53, 0x8b, 0x84, 0x84, 0xb8, 0x58, 0xf2, 0x12, 0x73, 0x53, 0x25, 0x18, 0x15, 0x18,
|
||||
0x35, 0x38, 0x83, 0xc0, 0xec, 0x24, 0x36, 0xb0, 0x52, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x2c, 0x6d, 0x58, 0x59, 0x3a, 0x00, 0x00, 0x00,
|
||||
}
|
||||
@@ -6,6 +6,13 @@ import (
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util/stringx"
|
||||
)
|
||||
|
||||
func formatFilename(filename string) string {
|
||||
return strings.ToLower(stringx.From(filename).ToCamel())
|
||||
func formatFilename(filename string, style NamingStyle) string {
|
||||
switch style {
|
||||
case namingCamel:
|
||||
return stringx.From(filename).ToCamel()
|
||||
case namingSnake:
|
||||
return stringx.From(filename).ToSnake()
|
||||
default:
|
||||
return strings.ToLower(stringx.From(filename).ToCamel())
|
||||
}
|
||||
}
|
||||
|
||||
17
tools/goctl/rpc/generator/filename_test.go
Normal file
17
tools/goctl/rpc/generator/filename_test.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestFormatFilename(t *testing.T) {
|
||||
assert.Equal(t, "abc", formatFilename("a_b_c", namingLower))
|
||||
assert.Equal(t, "ABC", formatFilename("a_b_c", namingCamel))
|
||||
assert.Equal(t, "a_b_c", formatFilename("a_b_c", namingSnake))
|
||||
assert.Equal(t, "a", formatFilename("a", namingSnake))
|
||||
assert.Equal(t, "A", formatFilename("a", namingCamel))
|
||||
// no flag to convert to snake
|
||||
assert.Equal(t, "abc", formatFilename("abc", namingSnake))
|
||||
}
|
||||
@@ -10,16 +10,18 @@ import (
|
||||
)
|
||||
|
||||
type RpcGenerator struct {
|
||||
g Generator
|
||||
g Generator
|
||||
style NamingStyle
|
||||
}
|
||||
|
||||
func NewDefaultRpcGenerator() *RpcGenerator {
|
||||
return NewRpcGenerator(NewDefaultGenerator())
|
||||
func NewDefaultRpcGenerator(style NamingStyle) *RpcGenerator {
|
||||
return NewRpcGenerator(NewDefaultGenerator(), style)
|
||||
}
|
||||
|
||||
func NewRpcGenerator(g Generator) *RpcGenerator {
|
||||
func NewRpcGenerator(g Generator, style NamingStyle) *RpcGenerator {
|
||||
return &RpcGenerator{
|
||||
g: g,
|
||||
g: g,
|
||||
style: style,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,42 +57,42 @@ func (g *RpcGenerator) Generate(src, target string, protoImportPath []string) er
|
||||
return err
|
||||
}
|
||||
|
||||
err = g.g.GenEtc(dirCtx, proto)
|
||||
err = g.g.GenEtc(dirCtx, proto, g.style)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = g.g.GenPb(dirCtx, protoImportPath, proto)
|
||||
err = g.g.GenPb(dirCtx, protoImportPath, proto, g.style)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = g.g.GenConfig(dirCtx, proto)
|
||||
err = g.g.GenConfig(dirCtx, proto, g.style)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = g.g.GenSvc(dirCtx, proto)
|
||||
err = g.g.GenSvc(dirCtx, proto, g.style)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = g.g.GenLogic(dirCtx, proto)
|
||||
err = g.g.GenLogic(dirCtx, proto, g.style)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = g.g.GenServer(dirCtx, proto)
|
||||
err = g.g.GenServer(dirCtx, proto, g.style)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = g.g.GenMain(dirCtx, proto)
|
||||
err = g.g.GenMain(dirCtx, proto, g.style)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = g.g.GenCall(dirCtx, proto)
|
||||
err = g.g.GenCall(dirCtx, proto, g.style)
|
||||
|
||||
console.NewColorConsole().MarkDone()
|
||||
|
||||
|
||||
@@ -1,128 +1,74 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"go/build"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tal-tech/go-zero/core/logx"
|
||||
"github.com/tal-tech/go-zero/core/stringx"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/rpc/execx"
|
||||
)
|
||||
|
||||
func TestRpcGenerateCaseNilImport(t *testing.T) {
|
||||
func TestRpcGenerate(t *testing.T) {
|
||||
_ = Clean()
|
||||
dispatcher := NewDefaultGenerator()
|
||||
if err := dispatcher.Prepare(); err == nil {
|
||||
g := NewRpcGenerator(dispatcher)
|
||||
abs, err := filepath.Abs("./test")
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = g.Generate("./test_stream.proto", abs, nil)
|
||||
defer func() {
|
||||
_ = os.RemoveAll(abs)
|
||||
}()
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, err = execx.Run("go test "+abs, abs)
|
||||
assert.Nil(t, err)
|
||||
err := dispatcher.Prepare()
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
projectName := stringx.Rand()
|
||||
g := NewRpcGenerator(dispatcher, namingLower)
|
||||
|
||||
func TestRpcGenerateCaseOption(t *testing.T) {
|
||||
_ = Clean()
|
||||
dispatcher := NewDefaultGenerator()
|
||||
if err := dispatcher.Prepare(); err == nil {
|
||||
g := NewRpcGenerator(dispatcher)
|
||||
abs, err := filepath.Abs("./test")
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = g.Generate("./test_option.proto", abs, nil)
|
||||
defer func() {
|
||||
_ = os.RemoveAll(abs)
|
||||
}()
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, err = execx.Run("go test "+abs, abs)
|
||||
assert.Nil(t, err)
|
||||
// case go path
|
||||
src := filepath.Join(build.Default.GOPATH, "src")
|
||||
_, err = os.Stat(src)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestRpcGenerateCaseWordOption(t *testing.T) {
|
||||
_ = Clean()
|
||||
dispatcher := NewDefaultGenerator()
|
||||
if err := dispatcher.Prepare(); err == nil {
|
||||
g := NewRpcGenerator(dispatcher)
|
||||
abs, err := filepath.Abs("./test")
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = g.Generate("./test_word_option.proto", abs, nil)
|
||||
defer func() {
|
||||
_ = os.RemoveAll(abs)
|
||||
}()
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, err = execx.Run("go test "+abs, abs)
|
||||
assert.Nil(t, err)
|
||||
projectDir := filepath.Join(src, projectName)
|
||||
srcDir := projectDir
|
||||
defer func() {
|
||||
_ = os.RemoveAll(srcDir)
|
||||
}()
|
||||
err = g.Generate("./test.proto", projectDir, []string{src})
|
||||
assert.Nil(t, err)
|
||||
_, err = execx.Run("go test "+projectName, projectDir)
|
||||
if err != nil {
|
||||
assert.Contains(t, err.Error(), "not in GOROOT")
|
||||
}
|
||||
}
|
||||
|
||||
// test keyword go
|
||||
func TestRpcGenerateCaseGoOption(t *testing.T) {
|
||||
_ = Clean()
|
||||
dispatcher := NewDefaultGenerator()
|
||||
if err := dispatcher.Prepare(); err == nil {
|
||||
g := NewRpcGenerator(dispatcher)
|
||||
abs, err := filepath.Abs("./test")
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = g.Generate("./test_go_option.proto", abs, nil)
|
||||
defer func() {
|
||||
_ = os.RemoveAll(abs)
|
||||
}()
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, err = execx.Run("go test "+abs, abs)
|
||||
assert.Nil(t, err)
|
||||
// case go mod
|
||||
workDir := t.TempDir()
|
||||
name := filepath.Base(workDir)
|
||||
_, err = execx.Run("go mod init "+name, workDir)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestRpcGenerateCaseImport(t *testing.T) {
|
||||
_ = Clean()
|
||||
dispatcher := NewDefaultGenerator()
|
||||
if err := dispatcher.Prepare(); err == nil {
|
||||
g := NewRpcGenerator(dispatcher)
|
||||
abs, err := filepath.Abs("./test")
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = g.Generate("./test_import.proto", abs, []string{"./base"})
|
||||
defer func() {
|
||||
_ = os.RemoveAll(abs)
|
||||
}()
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, err = execx.Run("go test "+abs, abs)
|
||||
assert.True(t, func() bool {
|
||||
return strings.Contains(err.Error(), "package base is not in GOROOT")
|
||||
}())
|
||||
projectDir = filepath.Join(workDir, projectName)
|
||||
err = g.Generate("./test.proto", projectDir, []string{src})
|
||||
assert.Nil(t, err)
|
||||
_, err = execx.Run("go test "+projectName, projectDir)
|
||||
if err != nil {
|
||||
assert.Contains(t, err.Error(), "not in GOROOT")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRpcGenerateCaseServiceRpcNamingSnake(t *testing.T) {
|
||||
_ = Clean()
|
||||
dispatcher := NewDefaultGenerator()
|
||||
if err := dispatcher.Prepare(); err == nil {
|
||||
g := NewRpcGenerator(dispatcher)
|
||||
abs, err := filepath.Abs("./test")
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = g.Generate("./test_service_rpc_naming_snake.proto", abs, nil)
|
||||
defer func() {
|
||||
_ = os.RemoveAll(abs)
|
||||
}()
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, err = execx.Run("go test "+abs, abs)
|
||||
assert.Nil(t, err)
|
||||
// case not in go mod and go path
|
||||
err = g.Generate("./test.proto", projectDir, []string{src})
|
||||
assert.Nil(t, err)
|
||||
_, err = execx.Run("go test "+projectName, projectDir)
|
||||
if err != nil {
|
||||
assert.Contains(t, err.Error(), "not in GOROOT")
|
||||
}
|
||||
|
||||
// invalid directory
|
||||
projectDir = filepath.Join(t.TempDir(), ".....")
|
||||
err = g.Generate("./test.proto", projectDir, nil)
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
@@ -59,12 +59,12 @@ func (m *default{{.serviceName}}) {{.method}}(ctx context.Context,in *{{.pbReque
|
||||
`
|
||||
)
|
||||
|
||||
func (g *defaultGenerator) GenCall(ctx DirContext, proto parser.Proto) error {
|
||||
func (g *defaultGenerator) GenCall(ctx DirContext, proto parser.Proto, namingStyle NamingStyle) error {
|
||||
dir := ctx.GetCall()
|
||||
service := proto.Service
|
||||
head := util.GetHead(proto.Name)
|
||||
|
||||
filename := filepath.Join(dir.Filename, fmt.Sprintf("%s.go", formatFilename(service.Name)))
|
||||
filename := filepath.Join(dir.Filename, fmt.Sprintf("%s.go", formatFilename(service.Name, namingStyle)))
|
||||
functions, err := g.genFunction(proto.PbPackage, service)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -81,13 +81,12 @@ func (g *defaultGenerator) GenCall(ctx DirContext, proto parser.Proto) error {
|
||||
}
|
||||
|
||||
var alias = collection.NewSet()
|
||||
for _, item := range service.RPC {
|
||||
alias.AddStr(fmt.Sprintf("%s = %s", parser.CamelCase(item.RequestType), fmt.Sprintf("%s.%s", proto.PbPackage, parser.CamelCase(item.RequestType))))
|
||||
alias.AddStr(fmt.Sprintf("%s = %s", parser.CamelCase(item.ReturnsType), fmt.Sprintf("%s.%s", proto.PbPackage, parser.CamelCase(item.ReturnsType))))
|
||||
for _, item := range proto.Message {
|
||||
alias.AddStr(fmt.Sprintf("%s = %s", parser.CamelCase(item.Name), fmt.Sprintf("%s.%s", proto.PbPackage, parser.CamelCase(item.Name))))
|
||||
}
|
||||
|
||||
err = util.With("shared").GoFmt(true).Parse(text).SaveTo(map[string]interface{}{
|
||||
"name": formatFilename(service.Name),
|
||||
"name": formatFilename(service.Name, namingStyle),
|
||||
"alias": strings.Join(alias.KeysStr(), util.NL),
|
||||
"head": head,
|
||||
"filePackage": dir.Base,
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/rpc/parser"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util/ctx"
|
||||
)
|
||||
|
||||
func TestGenerateCall(t *testing.T) {
|
||||
_ = Clean()
|
||||
project := "stream"
|
||||
abs, err := filepath.Abs("./test")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dir := filepath.Join(abs, project)
|
||||
err = util.MkdirIfNotExist(dir)
|
||||
assert.Nil(t, err)
|
||||
defer func() {
|
||||
_ = os.RemoveAll(abs)
|
||||
}()
|
||||
|
||||
projectCtx, err := ctx.Prepare(dir)
|
||||
assert.Nil(t, err)
|
||||
|
||||
p := parser.NewDefaultProtoParser()
|
||||
proto, err := p.Parse("./test_stream.proto")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dirCtx, err := mkdir(projectCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
|
||||
g := NewDefaultGenerator()
|
||||
err = g.Prepare()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = g.GenCall(dirCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
@@ -18,9 +18,9 @@ type Config struct {
|
||||
}
|
||||
`
|
||||
|
||||
func (g *defaultGenerator) GenConfig(ctx DirContext, _ parser.Proto) error {
|
||||
func (g *defaultGenerator) GenConfig(ctx DirContext, _ parser.Proto, namingStyle NamingStyle) error {
|
||||
dir := ctx.GetConfig()
|
||||
fileName := filepath.Join(dir.Filename, formatFilename("config")+".go")
|
||||
fileName := filepath.Join(dir.Filename, formatFilename("config", namingStyle)+".go")
|
||||
if util.FileExists(fileName) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/rpc/parser"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util/ctx"
|
||||
)
|
||||
|
||||
func TestGenerateConfig(t *testing.T) {
|
||||
_ = Clean()
|
||||
project := "stream"
|
||||
abs, err := filepath.Abs("./test")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dir := filepath.Join(abs, project)
|
||||
err = util.MkdirIfNotExist(dir)
|
||||
assert.Nil(t, err)
|
||||
defer func() {
|
||||
_ = os.RemoveAll(abs)
|
||||
}()
|
||||
|
||||
projectCtx, err := ctx.Prepare(dir)
|
||||
assert.Nil(t, err)
|
||||
|
||||
p := parser.NewDefaultProtoParser()
|
||||
proto, err := p.Parse("./test_stream.proto")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dirCtx, err := mkdir(projectCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
|
||||
g := NewDefaultGenerator()
|
||||
err = g.Prepare()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = g.GenConfig(dirCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// test file exists
|
||||
err = g.GenConfig(dirCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
@@ -4,12 +4,12 @@ import "github.com/tal-tech/go-zero/tools/goctl/rpc/parser"
|
||||
|
||||
type Generator interface {
|
||||
Prepare() error
|
||||
GenMain(ctx DirContext, proto parser.Proto) error
|
||||
GenCall(ctx DirContext, proto parser.Proto) error
|
||||
GenEtc(ctx DirContext, proto parser.Proto) error
|
||||
GenConfig(ctx DirContext, proto parser.Proto) error
|
||||
GenLogic(ctx DirContext, proto parser.Proto) error
|
||||
GenServer(ctx DirContext, proto parser.Proto) error
|
||||
GenSvc(ctx DirContext, proto parser.Proto) error
|
||||
GenPb(ctx DirContext, protoImportPath []string, proto parser.Proto) error
|
||||
GenMain(ctx DirContext, proto parser.Proto, namingStyle NamingStyle) error
|
||||
GenCall(ctx DirContext, proto parser.Proto, namingStyle NamingStyle) error
|
||||
GenEtc(ctx DirContext, proto parser.Proto, namingStyle NamingStyle) error
|
||||
GenConfig(ctx DirContext, proto parser.Proto, namingStyle NamingStyle) error
|
||||
GenLogic(ctx DirContext, proto parser.Proto, namingStyle NamingStyle) error
|
||||
GenServer(ctx DirContext, proto parser.Proto, namingStyle NamingStyle) error
|
||||
GenSvc(ctx DirContext, proto parser.Proto, namingStyle NamingStyle) error
|
||||
GenPb(ctx DirContext, protoImportPath []string, proto parser.Proto, namingStyle NamingStyle) error
|
||||
}
|
||||
|
||||
@@ -3,9 +3,11 @@ package generator
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/tal-tech/go-zero/tools/goctl/rpc/parser"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util/stringx"
|
||||
)
|
||||
|
||||
const etcTemplate = `Name: {{.serviceName}}.rpc
|
||||
@@ -16,9 +18,9 @@ Etcd:
|
||||
Key: {{.serviceName}}.rpc
|
||||
`
|
||||
|
||||
func (g *defaultGenerator) GenEtc(ctx DirContext, _ parser.Proto) error {
|
||||
func (g *defaultGenerator) GenEtc(ctx DirContext, _ parser.Proto, namingStyle NamingStyle) error {
|
||||
dir := ctx.GetEtc()
|
||||
serviceNameLower := formatFilename(ctx.GetMain().Base)
|
||||
serviceNameLower := formatFilename(ctx.GetMain().Base, namingStyle)
|
||||
fileName := filepath.Join(dir.Filename, fmt.Sprintf("%v.yaml", serviceNameLower))
|
||||
|
||||
text, err := util.LoadTemplate(category, etcTemplateFileFile, etcTemplate)
|
||||
@@ -27,6 +29,6 @@ func (g *defaultGenerator) GenEtc(ctx DirContext, _ parser.Proto) error {
|
||||
}
|
||||
|
||||
return util.With("etc").Parse(text).SaveTo(map[string]interface{}{
|
||||
"serviceName": serviceNameLower,
|
||||
"serviceName": strings.ToLower(stringx.From(ctx.GetMain().Base).ToCamel()),
|
||||
}, fileName, false)
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/rpc/parser"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util/ctx"
|
||||
)
|
||||
|
||||
func TestGenerateEtc(t *testing.T) {
|
||||
_ = Clean()
|
||||
project := "stream"
|
||||
abs, err := filepath.Abs("./test")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dir := filepath.Join(abs, project)
|
||||
err = util.MkdirIfNotExist(dir)
|
||||
assert.Nil(t, err)
|
||||
defer func() {
|
||||
_ = os.RemoveAll(abs)
|
||||
}()
|
||||
|
||||
projectCtx, err := ctx.Prepare(dir)
|
||||
assert.Nil(t, err)
|
||||
|
||||
p := parser.NewDefaultProtoParser()
|
||||
proto, err := p.Parse("./test_stream.proto")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dirCtx, err := mkdir(projectCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
|
||||
g := NewDefaultGenerator()
|
||||
err = g.Prepare()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = g.GenEtc(dirCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
@@ -46,10 +46,10 @@ func (l *{{.logicName}}) {{.method}} (in {{.request}}) ({{.response}}, error) {
|
||||
`
|
||||
)
|
||||
|
||||
func (g *defaultGenerator) GenLogic(ctx DirContext, proto parser.Proto) error {
|
||||
func (g *defaultGenerator) GenLogic(ctx DirContext, proto parser.Proto, namingStyle NamingStyle) error {
|
||||
dir := ctx.GetLogic()
|
||||
for _, rpc := range proto.Service.RPC {
|
||||
filename := filepath.Join(dir.Filename, formatFilename(rpc.Name+"_logic")+".go")
|
||||
filename := filepath.Join(dir.Filename, formatFilename(rpc.Name+"_logic", namingStyle)+".go")
|
||||
functions, err := g.genLogicFunction(proto.PbPackage, rpc)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/rpc/parser"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util/ctx"
|
||||
)
|
||||
|
||||
func TestGenerateLogic(t *testing.T) {
|
||||
project := "stream"
|
||||
abs, err := filepath.Abs("./test")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dir := filepath.Join(abs, project)
|
||||
err = util.MkdirIfNotExist(dir)
|
||||
assert.Nil(t, err)
|
||||
defer func() {
|
||||
_ = os.RemoveAll(abs)
|
||||
}()
|
||||
|
||||
projectCtx, err := ctx.Prepare(dir)
|
||||
assert.Nil(t, err)
|
||||
|
||||
p := parser.NewDefaultProtoParser()
|
||||
proto, err := p.Parse("./test_stream.proto")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dirCtx, err := mkdir(projectCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
|
||||
g := NewDefaultGenerator()
|
||||
err = g.Prepare()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = g.GenLogic(dirCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
@@ -45,9 +45,9 @@ func main() {
|
||||
}
|
||||
`
|
||||
|
||||
func (g *defaultGenerator) GenMain(ctx DirContext, proto parser.Proto) error {
|
||||
func (g *defaultGenerator) GenMain(ctx DirContext, proto parser.Proto, namingStyle NamingStyle) error {
|
||||
dir := ctx.GetMain()
|
||||
serviceNameLower := formatFilename(ctx.GetMain().Base)
|
||||
serviceNameLower := formatFilename(ctx.GetMain().Base, namingStyle)
|
||||
fileName := filepath.Join(dir.Filename, fmt.Sprintf("%v.go", serviceNameLower))
|
||||
imports := make([]string, 0)
|
||||
pbImport := fmt.Sprintf(`"%v"`, ctx.GetPb().Package)
|
||||
@@ -63,7 +63,7 @@ func (g *defaultGenerator) GenMain(ctx DirContext, proto parser.Proto) error {
|
||||
|
||||
return util.With("main").GoFmt(true).Parse(text).SaveTo(map[string]interface{}{
|
||||
"head": head,
|
||||
"serviceName": serviceNameLower,
|
||||
"serviceName": strings.ToLower(stringx.From(ctx.GetMain().Base).ToCamel()),
|
||||
"imports": strings.Join(imports, util.NL),
|
||||
"pkg": proto.PbPackage,
|
||||
"serviceNew": stringx.From(proto.Service.Name).ToCamel(),
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/rpc/parser"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util/ctx"
|
||||
)
|
||||
|
||||
func TestGenerateMain(t *testing.T) {
|
||||
_ = Clean()
|
||||
project := "stream"
|
||||
abs, err := filepath.Abs("./test")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dir := filepath.Join(abs, project)
|
||||
err = util.MkdirIfNotExist(dir)
|
||||
assert.Nil(t, err)
|
||||
defer func() {
|
||||
_ = os.RemoveAll(abs)
|
||||
}()
|
||||
|
||||
projectCtx, err := ctx.Prepare(dir)
|
||||
assert.Nil(t, err)
|
||||
|
||||
p := parser.NewDefaultProtoParser()
|
||||
proto, err := p.Parse("./test_stream.proto")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dirCtx, err := mkdir(projectCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
|
||||
g := NewDefaultGenerator()
|
||||
err = g.Prepare()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = g.GenMain(dirCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/tal-tech/go-zero/tools/goctl/rpc/parser"
|
||||
)
|
||||
|
||||
func (g *defaultGenerator) GenPb(ctx DirContext, protoImportPath []string, proto parser.Proto) error {
|
||||
func (g *defaultGenerator) GenPb(ctx DirContext, protoImportPath []string, proto parser.Proto, namingStyle NamingStyle) error {
|
||||
dir := ctx.GetPb()
|
||||
cw := new(bytes.Buffer)
|
||||
base := filepath.Dir(proto.Src)
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/rpc/parser"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util/ctx"
|
||||
)
|
||||
|
||||
func TestGenerateCaseNilImport(t *testing.T) {
|
||||
project := "stream"
|
||||
abs, err := filepath.Abs("./test")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dir := filepath.Join(abs, project)
|
||||
err = util.MkdirIfNotExist(dir)
|
||||
assert.Nil(t, err)
|
||||
defer func() {
|
||||
//_ = os.RemoveAll(abs)
|
||||
}()
|
||||
|
||||
projectCtx, err := ctx.Prepare(dir)
|
||||
assert.Nil(t, err)
|
||||
|
||||
p := parser.NewDefaultProtoParser()
|
||||
proto, err := p.Parse("./test_stream.proto")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dirCtx, err := mkdir(projectCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
|
||||
g := NewDefaultGenerator()
|
||||
if err := g.Prepare(); err == nil {
|
||||
targetPb := filepath.Join(dirCtx.GetPb().Filename, "test_stream.pb.go")
|
||||
err = g.GenPb(dirCtx, nil, proto)
|
||||
assert.Nil(t, err)
|
||||
assert.True(t, func() bool {
|
||||
return util.FileExists(targetPb)
|
||||
}())
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateCaseImport(t *testing.T) {
|
||||
project := "stream"
|
||||
abs, err := filepath.Abs("./test")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dir := filepath.Join(abs, project)
|
||||
err = util.MkdirIfNotExist(dir)
|
||||
assert.Nil(t, err)
|
||||
defer func() {
|
||||
_ = os.RemoveAll(abs)
|
||||
}()
|
||||
|
||||
projectCtx, err := ctx.Prepare(dir)
|
||||
assert.Nil(t, err)
|
||||
|
||||
p := parser.NewDefaultProtoParser()
|
||||
proto, err := p.Parse("./test_stream.proto")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dirCtx, err := mkdir(projectCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
|
||||
g := NewDefaultGenerator()
|
||||
if err := g.Prepare(); err == nil {
|
||||
err = g.GenPb(dirCtx, nil, proto)
|
||||
assert.Nil(t, err)
|
||||
|
||||
targetPb := filepath.Join(dirCtx.GetPb().Filename, "test_stream.pb.go")
|
||||
assert.True(t, func() bool {
|
||||
return util.FileExists(targetPb)
|
||||
}())
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateCasePathOption(t *testing.T) {
|
||||
project := "stream"
|
||||
abs, err := filepath.Abs("./test")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dir := filepath.Join(abs, project)
|
||||
err = util.MkdirIfNotExist(dir)
|
||||
assert.Nil(t, err)
|
||||
defer func() {
|
||||
_ = os.RemoveAll(abs)
|
||||
}()
|
||||
|
||||
projectCtx, err := ctx.Prepare(dir)
|
||||
assert.Nil(t, err)
|
||||
|
||||
p := parser.NewDefaultProtoParser()
|
||||
proto, err := p.Parse("./test_option.proto")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dirCtx, err := mkdir(projectCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
|
||||
g := NewDefaultGenerator()
|
||||
if err := g.Prepare(); err == nil {
|
||||
err = g.GenPb(dirCtx, nil, proto)
|
||||
assert.Nil(t, err)
|
||||
|
||||
targetPb := filepath.Join(dirCtx.GetPb().Filename, "test_option.pb.go")
|
||||
assert.True(t, func() bool {
|
||||
return util.FileExists(targetPb)
|
||||
}())
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateCaseWordOption(t *testing.T) {
|
||||
project := "stream"
|
||||
abs, err := filepath.Abs("./test")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dir := filepath.Join(abs, project)
|
||||
err = util.MkdirIfNotExist(dir)
|
||||
assert.Nil(t, err)
|
||||
defer func() {
|
||||
_ = os.RemoveAll(abs)
|
||||
}()
|
||||
|
||||
projectCtx, err := ctx.Prepare(dir)
|
||||
assert.Nil(t, err)
|
||||
|
||||
p := parser.NewDefaultProtoParser()
|
||||
proto, err := p.Parse("./test_word_option.proto")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dirCtx, err := mkdir(projectCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
|
||||
g := NewDefaultGenerator()
|
||||
if err := g.Prepare(); err == nil {
|
||||
|
||||
err = g.GenPb(dirCtx, nil, proto)
|
||||
assert.Nil(t, err)
|
||||
|
||||
targetPb := filepath.Join(dirCtx.GetPb().Filename, "test_word_option.pb.go")
|
||||
assert.True(t, func() bool {
|
||||
return util.FileExists(targetPb)
|
||||
}())
|
||||
}
|
||||
}
|
||||
|
||||
// test keyword go
|
||||
func TestGenerateCaseGoOption(t *testing.T) {
|
||||
project := "stream"
|
||||
abs, err := filepath.Abs("./test")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dir := filepath.Join(abs, project)
|
||||
err = util.MkdirIfNotExist(dir)
|
||||
assert.Nil(t, err)
|
||||
defer func() {
|
||||
_ = os.RemoveAll(abs)
|
||||
}()
|
||||
|
||||
projectCtx, err := ctx.Prepare(dir)
|
||||
assert.Nil(t, err)
|
||||
|
||||
p := parser.NewDefaultProtoParser()
|
||||
proto, err := p.Parse("./test_go_option.proto")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dirCtx, err := mkdir(projectCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
|
||||
g := NewDefaultGenerator()
|
||||
if err := g.Prepare(); err == nil {
|
||||
|
||||
err = g.GenPb(dirCtx, nil, proto)
|
||||
assert.Nil(t, err)
|
||||
|
||||
targetPb := filepath.Join(dirCtx.GetPb().Filename, "test_go_option.pb.go")
|
||||
assert.True(t, func() bool {
|
||||
return util.FileExists(targetPb)
|
||||
}())
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ func (s *{{.server}}Server) {{.method}} (ctx context.Context, in {{.request}}) (
|
||||
`
|
||||
)
|
||||
|
||||
func (g *defaultGenerator) GenServer(ctx DirContext, proto parser.Proto) error {
|
||||
func (g *defaultGenerator) GenServer(ctx DirContext, proto parser.Proto, namingStyle NamingStyle) error {
|
||||
dir := ctx.GetServer()
|
||||
logicImport := fmt.Sprintf(`"%v"`, ctx.GetLogic().Package)
|
||||
svcImport := fmt.Sprintf(`"%v"`, ctx.GetSvc().Package)
|
||||
@@ -54,7 +54,7 @@ func (g *defaultGenerator) GenServer(ctx DirContext, proto parser.Proto) error {
|
||||
|
||||
head := util.GetHead(proto.Name)
|
||||
service := proto.Service
|
||||
serverFile := filepath.Join(dir.Filename, formatFilename(service.Name+"_server")+".go")
|
||||
serverFile := filepath.Join(dir.Filename, formatFilename(service.Name+"_server", namingStyle)+".go")
|
||||
funcList, err := g.genFunctions(proto.PbPackage, service)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/rpc/parser"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util/ctx"
|
||||
)
|
||||
|
||||
func TestGenerateServer(t *testing.T) {
|
||||
_ = Clean()
|
||||
project := "stream"
|
||||
abs, err := filepath.Abs("./test")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dir := filepath.Join(abs, project)
|
||||
err = util.MkdirIfNotExist(dir)
|
||||
assert.Nil(t, err)
|
||||
defer func() {
|
||||
_ = os.RemoveAll(abs)
|
||||
}()
|
||||
|
||||
projectCtx, err := ctx.Prepare(dir)
|
||||
assert.Nil(t, err)
|
||||
|
||||
p := parser.NewDefaultProtoParser()
|
||||
proto, err := p.Parse("./test_stream.proto")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dirCtx, err := mkdir(projectCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
|
||||
g := NewDefaultGenerator()
|
||||
err = g.Prepare()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = g.GenServer(dirCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
@@ -23,9 +23,9 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
||||
}
|
||||
`
|
||||
|
||||
func (g *defaultGenerator) GenSvc(ctx DirContext, _ parser.Proto) error {
|
||||
func (g *defaultGenerator) GenSvc(ctx DirContext, _ parser.Proto, namingStyle NamingStyle) error {
|
||||
dir := ctx.GetSvc()
|
||||
fileName := filepath.Join(dir.Filename, formatFilename("service_context")+".go")
|
||||
fileName := filepath.Join(dir.Filename, formatFilename("service_context", namingStyle)+".go")
|
||||
text, err := util.LoadTemplate(category, svcTemplateFile, svcTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/rpc/parser"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util/ctx"
|
||||
)
|
||||
|
||||
func TestGenerateSvc(t *testing.T) {
|
||||
_ = Clean()
|
||||
project := "stream"
|
||||
abs, err := filepath.Abs("./test")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dir := filepath.Join(abs, project)
|
||||
err = util.MkdirIfNotExist(dir)
|
||||
assert.Nil(t, err)
|
||||
defer func() {
|
||||
_ = os.RemoveAll(abs)
|
||||
}()
|
||||
|
||||
projectCtx, err := ctx.Prepare(dir)
|
||||
assert.Nil(t, err)
|
||||
|
||||
p := parser.NewDefaultProtoParser()
|
||||
proto, err := p.Parse("./test_stream.proto")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dirCtx, err := mkdir(projectCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
|
||||
g := NewDefaultGenerator()
|
||||
err = g.GenSvc(dirCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"go/build"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tal-tech/go-zero/core/stringx"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/rpc/execx"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/rpc/parser"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util"
|
||||
"github.com/tal-tech/go-zero/tools/goctl/util/ctx"
|
||||
)
|
||||
|
||||
func TestMkDirInGoPath(t *testing.T) {
|
||||
dft := build.Default
|
||||
gp := dft.GOPATH
|
||||
if len(gp) == 0 {
|
||||
return
|
||||
}
|
||||
projectName := stringx.Rand()
|
||||
dir := filepath.Join(gp, "src", projectName)
|
||||
err := util.MkdirIfNotExist(dir)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer func() {
|
||||
_ = os.RemoveAll(dir)
|
||||
}()
|
||||
|
||||
projectCtx, err := ctx.Prepare(dir)
|
||||
assert.Nil(t, err)
|
||||
|
||||
p := parser.NewDefaultProtoParser()
|
||||
proto, err := p.Parse("./test.proto")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dirCtx, err := mkdir(projectCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
internal := filepath.Join(dir, "internal")
|
||||
assert.True(t, true, func() bool {
|
||||
return filepath.Join(dir, strings.ToLower(projectName)) == dirCtx.GetCall().Filename && projectName == dirCtx.GetCall().Package
|
||||
}())
|
||||
assert.True(t, true, func() bool {
|
||||
return filepath.Join(dir, "etc") == dirCtx.GetEtc().Filename && filepath.Join(projectName, "etc") == dirCtx.GetEtc().Package
|
||||
}())
|
||||
assert.True(t, true, func() bool {
|
||||
return internal == dirCtx.GetInternal().Filename && filepath.Join(projectName, "internal") == dirCtx.GetInternal().Package
|
||||
}())
|
||||
assert.True(t, true, func() bool {
|
||||
return filepath.Join(internal, "config") == dirCtx.GetConfig().Filename && filepath.Join(projectName, "internal", "config") == dirCtx.GetConfig().Package
|
||||
}())
|
||||
assert.True(t, true, func() bool {
|
||||
return filepath.Join(internal, "logic") == dirCtx.GetLogic().Filename && filepath.Join(projectName, "internal", "logic") == dirCtx.GetLogic().Package
|
||||
}())
|
||||
assert.True(t, true, func() bool {
|
||||
return filepath.Join(internal, "server") == dirCtx.GetServer().Filename && filepath.Join(projectName, "internal", "server") == dirCtx.GetServer().Package
|
||||
}())
|
||||
assert.True(t, true, func() bool {
|
||||
return filepath.Join(internal, "svc") == dirCtx.GetSvc().Filename && filepath.Join(projectName, "internal", "svc") == dirCtx.GetSvc().Package
|
||||
}())
|
||||
assert.True(t, true, func() bool {
|
||||
return filepath.Join(internal, strings.ToLower(proto.Service.Name)) == dirCtx.GetPb().Filename && filepath.Join(projectName, "internal", strings.ToLower(proto.Service.Name)) == dirCtx.GetPb().Package
|
||||
}())
|
||||
assert.True(t, true, func() bool {
|
||||
return dir == dirCtx.GetMain().Filename && projectName == dirCtx.GetMain().Package
|
||||
}())
|
||||
}
|
||||
|
||||
func TestMkDirInGoMod(t *testing.T) {
|
||||
dft := build.Default
|
||||
gp := dft.GOPATH
|
||||
if len(gp) == 0 {
|
||||
return
|
||||
}
|
||||
projectName := stringx.Rand()
|
||||
dir := filepath.Join(gp, "src", projectName)
|
||||
err := util.MkdirIfNotExist(dir)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = execx.Run("go mod init "+projectName, dir)
|
||||
assert.Nil(t, err)
|
||||
defer func() {
|
||||
_ = os.RemoveAll(dir)
|
||||
}()
|
||||
|
||||
projectCtx, err := ctx.Prepare(dir)
|
||||
assert.Nil(t, err)
|
||||
|
||||
p := parser.NewDefaultProtoParser()
|
||||
proto, err := p.Parse("./test.proto")
|
||||
assert.Nil(t, err)
|
||||
|
||||
dirCtx, err := mkdir(projectCtx, proto)
|
||||
assert.Nil(t, err)
|
||||
internal := filepath.Join(dir, "internal")
|
||||
assert.True(t, true, func() bool {
|
||||
return filepath.Join(dir, strings.ToLower(projectName)) == dirCtx.GetCall().Filename && projectName == dirCtx.GetCall().Package
|
||||
}())
|
||||
assert.True(t, true, func() bool {
|
||||
return filepath.Join(dir, "etc") == dirCtx.GetEtc().Filename && filepath.Join(projectName, "etc") == dirCtx.GetEtc().Package
|
||||
}())
|
||||
assert.True(t, true, func() bool {
|
||||
return internal == dirCtx.GetInternal().Filename && filepath.Join(projectName, "internal") == dirCtx.GetInternal().Package
|
||||
}())
|
||||
assert.True(t, true, func() bool {
|
||||
return filepath.Join(internal, "config") == dirCtx.GetConfig().Filename && filepath.Join(projectName, "internal", "config") == dirCtx.GetConfig().Package
|
||||
}())
|
||||
assert.True(t, true, func() bool {
|
||||
return filepath.Join(internal, "logic") == dirCtx.GetLogic().Filename && filepath.Join(projectName, "internal", "logic") == dirCtx.GetLogic().Package
|
||||
}())
|
||||
assert.True(t, true, func() bool {
|
||||
return filepath.Join(internal, "server") == dirCtx.GetServer().Filename && filepath.Join(projectName, "internal", "server") == dirCtx.GetServer().Package
|
||||
}())
|
||||
assert.True(t, true, func() bool {
|
||||
return filepath.Join(internal, "svc") == dirCtx.GetSvc().Filename && filepath.Join(projectName, "internal", "svc") == dirCtx.GetSvc().Package
|
||||
}())
|
||||
assert.True(t, true, func() bool {
|
||||
return filepath.Join(internal, strings.ToLower(proto.Service.Name)) == dirCtx.GetPb().Filename && filepath.Join(projectName, "internal", strings.ToLower(proto.Service.Name)) == dirCtx.GetPb().Package
|
||||
}())
|
||||
assert.True(t, true, func() bool {
|
||||
return dir == dirCtx.GetMain().Filename && projectName == dirCtx.GetMain().Package
|
||||
}())
|
||||
}
|
||||
24
tools/goctl/rpc/generator/naming.go
Normal file
24
tools/goctl/rpc/generator/naming.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package generator
|
||||
|
||||
type NamingStyle = string
|
||||
|
||||
const (
|
||||
namingLower NamingStyle = "lower"
|
||||
namingCamel NamingStyle = "camel"
|
||||
namingSnake NamingStyle = "snake"
|
||||
)
|
||||
|
||||
// IsNamingValid validates whether the namingStyle is valid or not,return
|
||||
// namingStyle and true if it is valid, or else return empty string
|
||||
// and false, and it is a valid value even namingStyle is empty string
|
||||
func IsNamingValid(namingStyle string) (NamingStyle, bool) {
|
||||
if len(namingStyle) == 0 {
|
||||
namingStyle = namingLower
|
||||
}
|
||||
switch namingStyle {
|
||||
case namingLower, namingCamel, namingSnake:
|
||||
return namingStyle, true
|
||||
default:
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
25
tools/goctl/rpc/generator/naming_test.go
Normal file
25
tools/goctl/rpc/generator/naming_test.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestIsNamingValid(t *testing.T) {
|
||||
style, valid := IsNamingValid("")
|
||||
assert.True(t, valid)
|
||||
assert.Equal(t, namingLower, style)
|
||||
|
||||
_, valid = IsNamingValid("lower1")
|
||||
assert.False(t, valid)
|
||||
|
||||
_, valid = IsNamingValid("lower")
|
||||
assert.True(t, valid)
|
||||
|
||||
_, valid = IsNamingValid("snake")
|
||||
assert.True(t, valid)
|
||||
|
||||
_, valid = IsNamingValid("camel")
|
||||
assert.True(t, valid)
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
@@ -9,13 +8,13 @@ import (
|
||||
)
|
||||
|
||||
func TestProtoTmpl(t *testing.T) {
|
||||
out, err := filepath.Abs("./test/test.proto")
|
||||
_ = Clean()
|
||||
// exists dir
|
||||
err := ProtoTmpl(t.TempDir())
|
||||
assert.Nil(t, err)
|
||||
defer func() {
|
||||
_ = os.RemoveAll(filepath.Dir(out))
|
||||
}()
|
||||
err = ProtoTmpl(out)
|
||||
assert.Nil(t, err)
|
||||
_, err = os.Stat(out)
|
||||
|
||||
// not exist dir
|
||||
dir := filepath.Join(t.TempDir(), "test")
|
||||
err = ProtoTmpl(dir)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package generator
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
@@ -10,87 +11,104 @@ import (
|
||||
)
|
||||
|
||||
func TestGenTemplates(t *testing.T) {
|
||||
err := util.InitTemplates(category, templates)
|
||||
_ = Clean()
|
||||
err := GenTemplates(nil)
|
||||
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)
|
||||
_ = Clean()
|
||||
err := GenTemplates(nil)
|
||||
assert.Nil(t, err)
|
||||
fp, err := util.GetTemplateDir(category)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
mainTpl := filepath.Join(fp, mainTemplateFile)
|
||||
data, err := ioutil.ReadFile(mainTpl)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, templates[mainTemplateFile], string(data))
|
||||
|
||||
err = RevertTemplate("test")
|
||||
if err != nil {
|
||||
assert.Equal(t, "test: no such file name", err.Error())
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(mainTpl, []byte("modify"), os.ModePerm)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
data, err = ioutil.ReadFile(mainTpl)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, "modify", string(data))
|
||||
|
||||
err = RevertTemplate(mainTemplateFile)
|
||||
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))
|
||||
data, err = ioutil.ReadFile(mainTpl)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, templates[mainTemplateFile], string(data))
|
||||
}
|
||||
|
||||
func TestClean(t *testing.T) {
|
||||
name := "main.tpl"
|
||||
err := util.InitTemplates(category, templates)
|
||||
_ = Clean()
|
||||
err := GenTemplates(nil)
|
||||
assert.Nil(t, err)
|
||||
fp, err := util.GetTemplateDir(category)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
mainTpl := filepath.Join(fp, mainTemplateFile)
|
||||
_, err = os.Stat(mainTpl)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Nil(t, Clean())
|
||||
|
||||
dir, err := util.GetTemplateDir(category)
|
||||
err = Clean()
|
||||
assert.Nil(t, err)
|
||||
|
||||
file := filepath.Join(dir, name)
|
||||
_, err = ioutil.ReadFile(file)
|
||||
_, err = os.Stat(mainTpl)
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestUpdate(t *testing.T) {
|
||||
name := "main.tpl"
|
||||
err := util.InitTemplates(category, templates)
|
||||
_ = Clean()
|
||||
err := GenTemplates(nil)
|
||||
assert.Nil(t, err)
|
||||
fp, err := util.GetTemplateDir(category)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
mainTpl := filepath.Join(fp, mainTemplateFile)
|
||||
|
||||
err = ioutil.WriteFile(mainTpl, []byte("modify"), os.ModePerm)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadFile(mainTpl)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, "modify", string(data))
|
||||
|
||||
err = Update(category)
|
||||
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))
|
||||
data, err = ioutil.ReadFile(mainTpl)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, templates[mainTemplateFile], string(data))
|
||||
}
|
||||
|
||||
func TestGetCategory(t *testing.T) {
|
||||
assert.Equal(t, category, GetCategory())
|
||||
_ = Clean()
|
||||
result := GetCategory()
|
||||
assert.Equal(t, category, result)
|
||||
}
|
||||
|
||||
@@ -2,24 +2,61 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package test;
|
||||
option go_package = "go";
|
||||
|
||||
import "test_base.proto";
|
||||
import "base/common.proto";
|
||||
import "google/protobuf/any.proto";
|
||||
|
||||
message TestMessage {
|
||||
base.CommonReq req = 1;
|
||||
}
|
||||
message TestReq {}
|
||||
message TestReply {
|
||||
base.CommonReply reply = 2;
|
||||
option go_package = "github.com/test";
|
||||
|
||||
message Req {
|
||||
string in = 1;
|
||||
common.User user = 2;
|
||||
google.protobuf.Any object = 4;
|
||||
}
|
||||
|
||||
enum TestEnum {
|
||||
unknown = 0;
|
||||
male = 1;
|
||||
female = 2;
|
||||
message Reply {
|
||||
string out = 1;
|
||||
}
|
||||
|
||||
service TestService {
|
||||
rpc TestRpc (TestReq) returns (TestReply);
|
||||
message snake_req {}
|
||||
|
||||
message snake_reply {}
|
||||
|
||||
message CamelReq{}
|
||||
|
||||
message CamelReply{}
|
||||
|
||||
message EnumMessage {
|
||||
enum Enum {
|
||||
unknown = 0;
|
||||
male = 1;
|
||||
female = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message CommonReply{}
|
||||
|
||||
message MapReq{
|
||||
map<string, string> m = 1;
|
||||
}
|
||||
|
||||
message RepeatedReq{
|
||||
repeated string id = 1;
|
||||
}
|
||||
|
||||
service Test_Service {
|
||||
// service
|
||||
rpc Service (Req) returns (Reply);
|
||||
// greet service
|
||||
rpc GreetService (Req) returns (Reply);
|
||||
// case snake
|
||||
rpc snake_service (snake_req) returns (snake_reply);
|
||||
// case camel
|
||||
rpc CamelService (CamelReq) returns (CamelReply);
|
||||
// case enum
|
||||
rpc EnumService (EnumMessage) returns (CommonReply);
|
||||
// case map
|
||||
rpc MapService (MapReq) returns (CommonReply);
|
||||
// case repeated
|
||||
rpc RepeatedService (RepeatedReq) returns (CommonReply);
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
// test proto
|
||||
syntax = "proto3";
|
||||
|
||||
package base;
|
||||
|
||||
message CommonReq {
|
||||
string in = 1;
|
||||
}
|
||||
|
||||
message CommonReply {
|
||||
string out = 1;
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
// test proto
|
||||
syntax = "proto3";
|
||||
|
||||
package stream;
|
||||
|
||||
option go_package="go";
|
||||
|
||||
message StreamReq {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message StreamResp {
|
||||
string greet = 1;
|
||||
}
|
||||
|
||||
service StreamGreeter {
|
||||
rpc greet (StreamReq) returns (StreamResp);
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
// test proto
|
||||
syntax = "proto3";
|
||||
|
||||
package greet;
|
||||
import "base/common.proto";
|
||||
|
||||
message In {
|
||||
string name = 1;
|
||||
common.User user = 2;
|
||||
}
|
||||
|
||||
message Out {
|
||||
string greet = 1;
|
||||
}
|
||||
|
||||
service StreamGreeter {
|
||||
rpc greet (In) returns (Out);
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
// test proto
|
||||
syntax = "proto3";
|
||||
|
||||
package stream;
|
||||
|
||||
option go_package="github.com/tal-tech/go-zero";
|
||||
|
||||
message StreamReq {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message StreamResp {
|
||||
string greet = 1;
|
||||
}
|
||||
|
||||
service StreamGreeter {
|
||||
rpc greet (StreamReq) returns (StreamResp);
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
// test proto
|
||||
syntax = "proto3";
|
||||
|
||||
package snake_package;
|
||||
|
||||
message StreamReq {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message Stream_Resp {
|
||||
string greet = 1;
|
||||
}
|
||||
|
||||
message lowercase {
|
||||
string in = 1;
|
||||
string lower = 2;
|
||||
}
|
||||
|
||||
message CamelCase {
|
||||
string Camel = 1;
|
||||
}
|
||||
|
||||
service Stream_Greeter {
|
||||
rpc snake_service(StreamReq) returns (Stream_Resp);
|
||||
rpc ServiceCamelCase(CamelCase) returns (CamelCase);
|
||||
rpc servicelowercase(lowercase) returns (lowercase);
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
// test proto
|
||||
syntax = "proto3";
|
||||
|
||||
package stream;
|
||||
|
||||
message StreamReq {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message StreamResp {
|
||||
string greet = 1;
|
||||
}
|
||||
|
||||
service StreamGreeter {
|
||||
// greet service
|
||||
rpc greet (StreamReq) returns (StreamResp);
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
// test proto
|
||||
syntax = "proto3";
|
||||
|
||||
package stream;
|
||||
|
||||
option go_package="user";
|
||||
|
||||
message StreamReq {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message StreamResp {
|
||||
string greet = 1;
|
||||
}
|
||||
|
||||
service StreamGreeter {
|
||||
rpc greet(StreamReq) returns (StreamResp);
|
||||
}
|
||||
Reference in New Issue
Block a user