Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

添加对常用 CURD 的接口生成 #18

Merged
merged 2 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cli/gen_all.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ var GenAllHooks = []GenHook{
runGenMod,
runEditorconfig,
runGenState,
runGenImpl,
}

var genAllCmd = &cobra.Command{
Expand Down
27 changes: 27 additions & 0 deletions cli/gen_impl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package cli

import (
"github.com/lazygophers/codegen/codegen"
"github.com/lazygophers/log"
"github.com/spf13/cobra"
)

var genImplCmd = &cobra.Command{
Use: "impl",
Short: "Generate implementation files",
RunE: runGenImpl,
}

var runGenImpl = func(cmd *cobra.Command, args []string) (err error) {
err = codegen.GenerateImpl(pb)
if err != nil {
log.Errorf("err:%v", err)
return err
}

return nil
}

func init() {
genCmd.AddCommand(genImplCmd)
}
22 changes: 8 additions & 14 deletions codegen/generate_add_rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
action.Roles = append(action.Roles, p.DefaultRole)
}

action.Roles = candy.Unique(action.Roles)

Check failure on line 58 in codegen/generate_add_rpc.go

View workflow job for this annotation

GitHub Actions / lint

undefined: candy.Unique (typecheck)
}
}

Expand Down Expand Up @@ -152,16 +152,7 @@
}

// NOTE: 寻找主键
var pkField *PbNormalField
{
for _, field := range msg.normalFields {
// 先简单粗暴用 id 当作主键,后面再改
if field.Name == "id" {
pkField = field
break
}
}
}
pkField := msg.PrimaryField()

var rpcBlock string

Expand All @@ -170,15 +161,18 @@
args := map[string]interface{}{
"PB": pb,
"Model": opt.Model,
"Role": role,
"Action": action,
"GenTo": opt.GenTo,
"ListOptions": opt.ListOptions,
}

if role != "" {
args["Role"] = role
}

if pkField != nil {
args["PprimaryKey"] = pkField.Name
args["PprimaryKeyType"] = pkField.Type()
args["PrimaryKey"] = pkField.Name
args["PrimaryKeyType"] = pkField.Type()
}

var rpcName string
Expand Down Expand Up @@ -217,7 +211,7 @@

// 处理 server.rpc
if rpc := pb.GetRPC(rpcName); rpc == nil {
tpl, err := GetTemplate(TemplateTypeProtoService)
tpl, err := GetTemplate(TemplateTypeProtoRpc)
if err != nil {
log.Errorf("err:%v", err)
return err
Expand Down
176 changes: 176 additions & 0 deletions codegen/generate_impl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
package codegen

import (
"github.com/lazygophers/log"
"github.com/lazygophers/utils/osx"
"github.com/pterm/pterm"
"io/fs"
"os"
"path/filepath"
)

func initImplDirectory(pb *PbPackage) error {
if osx.IsDir(GetPath(PathTypeImpl, pb)) {
return nil
}

err := os.MkdirAll(GetPath(PathTypeImpl, pb), fs.ModePerm)
if err != nil {
log.Errorf("err:%s", err)
return err
}

return nil
}

func initImplFile(pb *PbPackage, genTo string) (err error) {
p := filepath.Join(GetPath(PathTypeImpl, pb), genTo+".go")
if osx.IsFile(p) {
return nil
}

tpl, err := GetTemplate(TemplateTypeImpl)
if err != nil {
log.Errorf("err:%v", err)
return err
}

file, err := os.OpenFile(p, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, fs.FileMode(0666))
if err != nil {
log.Errorf("err:%v", err)
return err
}
defer file.Close()

err = tpl.Execute(file, map[string]interface{}{
"PB": pb,
})
if err != nil {
log.Errorf("err:%v", err)
return err
}

_, err = file.WriteString("\n")
if err != nil {
log.Errorf("err:%v", err)
return err
}

return nil
}

func generateImpl(pb *PbPackage, rpc *PbRPC) (err error) {
pterm.Info.Printfln("try generate impl %s to %s", rpc.Name, rpc.genOption.GenTo)

err = initImplFile(pb, rpc.genOption.GenTo)
if err != nil {
log.Errorf("err:%v", err)
return err
}

path := filepath.Join(GetPath(PathTypeImpl, pb), rpc.genOption.GenTo+".go")

log.Infof("gen impl action %s", rpc.genOption.Action)

// TODO: 缓存
goFile, err := ParseGoFile(path)
if err != nil {
log.Errorf("err:%v", err)
return err
}

for _, goFunc := range goFile.funcs {
if goFunc.RecvType != "" {
continue
}

if goFunc.Name == rpc.Name {
pterm.Warning.Printfln("%s is exist, skip generate", rpc.Name)
return nil
}
}

args := map[string]any{
"PB": pb,
"RpcName": rpc.Name,
"RequestType": rpc.rpc.RequestType,
"ResponseType": rpc.rpc.ReturnsType,
}

if rpc.genOption.Model != "" {
log.Infof("model:%s", rpc.genOption.Model)

args["Model"] = rpc.genOption.Model

msg := pb.GetMessage(rpc.genOption.Model)
if msg != nil {
pkField := msg.PrimaryField()
if pkField != nil {
args["PrimaryKey"] = pkField.Name
args["PrimaryKeyType"] = pkField.Type()
}
}
}

tpl, err := GetTemplate(TemplateTypeImplAction, rpc.genOption.Action)
if err != nil {
log.Errorf("err:%v", err)
return err
}

file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, fs.FileMode(0666))
if err != nil {
log.Errorf("err:%v", err)
return err
}
defer file.Close()

//_, err = file.Seek(0, io.SeekEnd)
//if err != nil {
// log.Errorf("err:%v", err)
// return err
//}

err = tpl.Execute(file, args)
if err != nil {
log.Errorf("err:%v", err)
return err
}

_, err = file.WriteString("\n")
if err != nil {
log.Errorf("err:%v", err)
return err
}

pterm.Success.Printfln("generate %s success", rpc.Name)

return nil
}

func GenerateImpl(pb *PbPackage) (err error) {
pterm.Info.Printfln("Generating impl directory...")

err = initImplDirectory(pb)
if err != nil {
log.Errorf("err:%v", err)
return err
}

log.Info("————————————————————分割线————————————————")

for _, rpc := range pb.RPCs() {
err = generateImpl(pb, rpc)
if err != nil {
log.Errorf("err:%v", err)
return err
}

log.Info(rpc.Name)
log.Info(rpc.options)
log.Info(rpc.comment)
log.Info(rpc.genOption)
}

return nil
}
17 changes: 8 additions & 9 deletions codegen/goparse.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,15 +178,15 @@ type GoStruct struct {
}

type GoFile struct {
Imports []*GoImport
Funcs []*GoFunc
Structs []*GoStruct
imports []*GoImport
funcs []*GoFunc
structs []*GoStruct
}

func (p *GoPackage) buildFuncMap() {
p.FuncMap = map[string]*GoFuncNode{}
for _, v := range p.FileMap {
for _, x := range v.Funcs {
for _, x := range v.funcs {
p.FuncMap[x.Name] = &GoFuncNode{
goFunc: x,
goFile: v,
Expand Down Expand Up @@ -370,7 +370,7 @@ func fetchImports(ctx *GoContext, f *ast.File, goFile *GoFile) {
goImport.Name = path.Base(goImport.Path)
}
}
goFile.Imports = append(goFile.Imports, goImport)
goFile.imports = append(goFile.imports, goImport)
}
}
func getSelectorExprIndents(ctx *GoContext, c ast.Expr, goFunc *GoFunc) []string {
Expand Down Expand Up @@ -621,13 +621,12 @@ func parseFuncDecl(ctx *GoContext, f *ast.FuncDecl) *GoFunc {
}

func fetchFunc(ctx *GoContext, f *ast.FuncDecl, goFile *GoFile) {
log.Info(f.Doc)
goFunc := parseFuncDecl(ctx, f)
if goFunc == nil {
return
}

goFile.Funcs = append(goFile.Funcs, goFunc)
goFile.funcs = append(goFile.funcs, goFunc)
}
func fetchType(ctx *GoContext, ts *ast.TypeSpec, goFile *GoFile) {
if ts.Type == nil {
Expand All @@ -642,7 +641,7 @@ func fetchType(ctx *GoContext, ts *ast.TypeSpec, goFile *GoFile) {
}
switch ts.Type.(type) {
case *ast.StructType:
goFile.Structs = append(goFile.Structs, &GoStruct{
goFile.structs = append(goFile.structs, &GoStruct{
Name: name,
})
}
Expand Down Expand Up @@ -800,7 +799,7 @@ func (p *ScanErrCodeContext) Scan(mod, name string) {
// 找下这个模块的 path
goFile := node.goFile
var impPath string
for _, x := range goFile.Imports {
for _, x := range goFile.imports {
if x.Name == callMod {
impPath = x.Path
break
Expand Down
6 changes: 6 additions & 0 deletions codegen/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ const (
PathTypeTableField

PathTypeInternal

PathTypeState
PathTypeStateTable
PathTypeStateConf
PathTypeStateCache
PathTypeStateState

PathTypeImpl
)

func GetPath(t PathType, pb *PbPackage) string {
Expand Down Expand Up @@ -59,6 +62,9 @@ func GetPath(t PathType, pb *PbPackage) string {
case PathTypeStateState:
return filepath.Join(GetPath(PathTypeState, pb), "state.go")

case PathTypeImpl:
return filepath.Join(GetPath(PathTypeInternal, pb), "impl")

default:
panic("unsupported path type")
}
Expand Down
Loading
Loading