mirror of
https://github.com/go-home-admin/toolset.git
synced 2026-04-22 16:17:04 +08:00
280 lines
7.2 KiB
Go
280 lines
7.2 KiB
Go
package commands
|
|
|
|
import (
|
|
"bytes"
|
|
"github.com/ctfang/command"
|
|
"github.com/go-home-admin/toolset/parser"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
)
|
|
|
|
// RouteCommand @Bean
|
|
type RouteCommand struct{}
|
|
|
|
func (RouteCommand) Configure() command.Configure {
|
|
return command.Configure{
|
|
Name: "make:route",
|
|
Description: "根据protoc文件定义, 生成路由信息和控制器文件",
|
|
Input: command.Argument{
|
|
Option: []command.ArgParam{
|
|
{
|
|
Name: "path",
|
|
Description: "只解析指定目录",
|
|
Default: "@root/protobuf",
|
|
},
|
|
{
|
|
Name: "out_route",
|
|
Description: "生成文件到指定目录",
|
|
Default: "@root/routes",
|
|
},
|
|
{
|
|
Name: "out_actions",
|
|
Description: "生成文件到指定目录",
|
|
Default: "@root/app/http",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func (RouteCommand) Execute(input command.Input) {
|
|
root := getRootPath()
|
|
module := getModModule()
|
|
out := input.GetOption("out_route")
|
|
out = strings.Replace(out, "@root", root, 1)
|
|
|
|
outHttp := input.GetOption("out_actions")
|
|
outHttp = strings.Replace(outHttp, "@root", root, 1)
|
|
|
|
path := input.GetOption("path")
|
|
path = strings.Replace(path, "@root", root, 1)
|
|
|
|
agl := map[string]*ApiGroups{}
|
|
|
|
for _, parsers := range parser.NewProtocParserForDir(path) {
|
|
for _, fileParser := range parsers {
|
|
for _, service := range fileParser.Services {
|
|
group := ""
|
|
|
|
for _, option := range service.Opt {
|
|
if option.Key == "http.RouteGroup" {
|
|
group = option.Val
|
|
if _, ok := agl[group]; !ok {
|
|
agl[group] = &ApiGroups{
|
|
name: group,
|
|
imports: map[string]string{
|
|
"home_api_1": "github.com/go-home-admin/home/bootstrap/http/api",
|
|
"home_gin_1": "github.com/gin-gonic/gin",
|
|
},
|
|
controllers: make([]Controller, 0),
|
|
servers: make([]parser.Service, 0),
|
|
}
|
|
}
|
|
genController(service, outHttp)
|
|
break
|
|
}
|
|
}
|
|
|
|
if group != "" {
|
|
g := agl[group]
|
|
imports := module + "/app/http/" + fileParser.PackageName + "/" + parser.StringToSnake(service.Name)
|
|
g.imports[imports] = imports
|
|
|
|
g.controllers = append(g.controllers, Controller{
|
|
name: service.Name,
|
|
alias: imports,
|
|
})
|
|
|
|
g.servers = append(g.servers, service)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for _, g := range agl {
|
|
genRoute(g, out)
|
|
}
|
|
cmd := exec.Command("go", []string{"fmt", out}...)
|
|
var outBuffer bytes.Buffer
|
|
cmd.Stdout = &outBuffer
|
|
cmd.Stderr = os.Stderr
|
|
cmd.Dir = out
|
|
_ = cmd.Run()
|
|
}
|
|
|
|
func genController(server parser.Service, out string) {
|
|
page := server.Protoc.PackageName
|
|
out += "/" + page + "/" + parser.StringToSnake(server.Name)
|
|
|
|
if !parser.DirIsExist(out) {
|
|
_ = os.MkdirAll(out, 0760)
|
|
}
|
|
|
|
conStr := `package {package}
|
|
|
|
// Controller @Bean
|
|
type Controller struct {
|
|
}`
|
|
conStr = strings.ReplaceAll(conStr, "{package}", parser.StringToSnake(server.Name))
|
|
err := os.WriteFile(out+"/controller.go", []byte(conStr), 0760)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
methodStr := `package {package}
|
|
|
|
import ({import})
|
|
|
|
// {action} {doc}
|
|
func (receiver *Controller) {action}(req *{controllerAlias}.{param}, ctx *gin.Context) (*{controllerAlias}.{return}, error) {
|
|
// TODO 这里写业务
|
|
return &{controllerAlias}.{return}{}, nil
|
|
}
|
|
|
|
// GinHandle{action} gin原始路由处理
|
|
// http.{method}({url})
|
|
func (receiver *Controller) GinHandle{action}(ctx *gin.Context) {
|
|
req := &{controllerAlias}.{param}{}
|
|
err := ctx.ShouldBind(req)
|
|
|
|
if err != nil {
|
|
{providers}.ErrorRequest(ctx, err)
|
|
return
|
|
}
|
|
|
|
resp, err := receiver.{action}(req, ctx)
|
|
if err != nil {
|
|
{providers}.ErrorResponse(ctx, err)
|
|
return
|
|
}
|
|
|
|
{providers}.SuccessResponse(ctx, resp)
|
|
}
|
|
`
|
|
gin := "github.com/gin-gonic/gin"
|
|
providers := "github.com/go-home-admin/home/app/providers"
|
|
imports := map[string]string{gin: gin, providers: providers}
|
|
goMod := getModModule()
|
|
|
|
for rName, rpc := range server.Rpc {
|
|
for _, option := range rpc.Opt {
|
|
if strings.Index(option.Key, "http.") == 0 {
|
|
serPage := goMod + "/generate/proto/" + server.Protoc.PackageName
|
|
imports[serPage] = serPage
|
|
importsStr := ""
|
|
m := genImportAlias(imports)
|
|
sk := sortMap(m)
|
|
for _, s := range sk {
|
|
importsStr += "\n\t" + m[s] + " \"" + s + "\""
|
|
}
|
|
|
|
controllerAlias := m[serPage]
|
|
|
|
str := methodStr
|
|
actionName := parser.StringToHump(rName)
|
|
|
|
i := strings.Index(option.Key, ".")
|
|
method := option.Key[i+1:]
|
|
url := option.Val
|
|
|
|
for s, O := range map[string]string{
|
|
"{package}": parser.StringToSnake(server.Name),
|
|
"{import}": importsStr + "\n",
|
|
"{doc}": rpc.Doc,
|
|
"{method}": method,
|
|
"{url}": url,
|
|
"{action}": actionName,
|
|
"{controllerAlias}": controllerAlias,
|
|
"{providers}": m[providers],
|
|
"{param}": rpc.Param,
|
|
"{return}": rpc.Return,
|
|
} {
|
|
str = strings.ReplaceAll(str, s, O)
|
|
}
|
|
|
|
err = os.WriteFile(out+"/"+parser.StringToSnake(actionName)+"_action.go", []byte(str), 0766)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func genRoute(g *ApiGroups, out string) {
|
|
context := make([]string, 0)
|
|
context = append(context, "package routes")
|
|
|
|
// import
|
|
importAlias := genImportAlias(g.imports)
|
|
if len(importAlias) != 0 {
|
|
context = append(context, "\nimport ("+parser.GetImportStrForMap(importAlias)+"\n)")
|
|
}
|
|
// Routes struct
|
|
context = append(context, genRoutesStruct(g, importAlias))
|
|
// Routes struct func GetRoutes
|
|
context = append(context, genRoutesFunc(g, importAlias))
|
|
|
|
str := "// gen for home toolset"
|
|
for _, s2 := range context {
|
|
str = str + "\n" + s2
|
|
}
|
|
err := os.WriteFile(out+"/"+parser.StringToSnake(g.name)+"_gen.go", []byte(str), 0766)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func genRoutesFunc(g *ApiGroups, m map[string]string) string {
|
|
homeGin := m["github.com/gin-gonic/gin"]
|
|
homeApi := m["github.com/go-home-admin/home/bootstrap/http/api"]
|
|
|
|
str := "func (c *" + parser.StringToHump(g.name) + "Routes) GetGroup() string {" +
|
|
"\n\treturn \"" + g.name + "\"" +
|
|
"\n}"
|
|
|
|
str += "\nfunc (c *" + parser.StringToHump(g.name) + "Routes) GetRoutes() map[*" + homeApi + ".Config]func(c *" + homeGin + ".Context) {" +
|
|
"\n\treturn map[*" + homeApi + ".Config]func(c *" + homeGin + ".Context){"
|
|
|
|
for _, server := range g.servers {
|
|
for rName, rpc := range server.Rpc {
|
|
for _, option := range rpc.Opt {
|
|
if strings.Index(option.Key, "http.") == 0 {
|
|
i := strings.Index(option.Key, ".")
|
|
method := option.Key[i+1:]
|
|
str += "\n\t\t" + homeApi + "." + method + "(\"" + option.Val + "\"):" +
|
|
"c." + parser.StringToSnake(server.Name) + ".GinHandle" + parser.StringToHump(rName) + ","
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return str + "\n\t}\n}"
|
|
}
|
|
|
|
func genRoutesStruct(g *ApiGroups, m map[string]string) string {
|
|
str := "\n// @Bean" +
|
|
"\ntype " + parser.StringToHump(g.name) + "Routes struct {\n"
|
|
for _, controller := range g.controllers {
|
|
alias := m[controller.alias]
|
|
str += "\t" + parser.StringToSnake(controller.name) + " *" + alias + ".Controller" + " `inject:\"\"`\n"
|
|
}
|
|
|
|
return str + "}\n"
|
|
}
|
|
|
|
type ApiGroups struct {
|
|
name string
|
|
imports map[string]string
|
|
controllers []Controller
|
|
servers []parser.Service
|
|
}
|
|
|
|
type Controller struct {
|
|
name string
|
|
alias string
|
|
ty string // *alias.Controller
|
|
}
|