// // cli_gen.go // Copyright (C) 2023 tiglog // // Distributed under terms of the MIT license. // package gconsole import ( "errors" "flag" "fmt" "os" "strings" "text/template" "git.hexq.cn/tiglog/golib/gfile" "git.hexq.cn/tiglog/golib/helper" ) type gen_cmd struct { BaseCmd } func NewGenCmd(cli IConsole) *gen_cmd { return &gen_cmd{ BaseCmd{ Name: "gen", Desc: "代码生成", }, } } func (c *gen_cmd) Init(args []string) { if len(args) == 0 { return } name := args[0] args = args[1:] cmd := flag.NewFlagSet(name, flag.ExitOnError) switch name { case "model": c.initModelCmd(cmd, args) case "cmd": c.initCmdCmd(cmd, args) case "api": c.initApiCmd(cmd, args) } } // model template {{{ const tpl_ent = `package {{.name}} import ( "time" "git.hexq.cn/tiglog/golib/helper" "git.hexq.cn/tiglog/mydb" ) const Table = "{{.table_name}}" type {{.table_ent}} struct { Id int64 ` + "`json:\"id\" db:\"id,omitempty\"`" + ` CreatedAt *time.Time ` + "`json:\"created_at\" db:\"created_at,omitempty\"`" + ` UpdatedAt *time.Time ` + "`json:\"updated_at\" db:\"updated_at,omitempty\"`" + ` } ` var tpl_store = `package {{.name}} import ( "git.hexq.cn/tiglog/golib/helper" "git.hexq.cn/tiglog/mydb" ) var _ = interface { mydb.Record mydb.BeforeUpdateHook mydb.BeforeCreateHook }(&{{.table_ent}}{}) func (e *{{.table_ent}}) Store(sess mydb.Session) mydb.Store { return sess.Collection(Table) } func (e *{{.table_ent}}) BeforeCreate(sess mydb.Session) error { if err := e.BeforeUpdate(sess); err != nil { return err } e.CreatedAt = helper.GetTimeUTCPointer() return nil } func (e *{{.table_ent}}) BeforeUpdate(sess mydb.Session) error { e.UpdatedAt = helper.GetTimeUTCPointer() return nil } type entStore struct { mydb.Collection } var _ = interface { mydb.Store }(&entStore{}) var _store *EntStore func RegisterStore(sess mydb.Session) *entStore { _store = &entStore{sess.Collection(Table)} return _store } func GetStore() *entStore { return _store } ` // }}} func (c *gen_cmd) initModelCmd(cmd *flag.FlagSet, args []string) { var ( name string table string ) cmd.StringVar(&name, "name", "", "实体名称, eg: sys_user") cmd.StringVar(&table, "table", "", "数据表名称,可空, eg: sys_users") cmd.Parse(args) c.Action = func() error { if name == "" { return errors.New("name 不能为空") } var fp = "./innernal/models/" + name if !gfile.Exists(fp) { err := os.Mkdir(fp, 0755) if err != nil { return err } } var table_ent string if table == "" { table_ent = helper.CamelString(name) } var table_names = helper.NewPluralizeClient().Plural(name) data := map[string]string{ "name": name, "table_name": table_names, "table_ent": table_ent, } // 创建 ent fp_ent := fp + "/ent.go" if gfile.Exists(fp_ent) { fmt.Printf("SKIP for ent %s 存在\n", fp_ent) } else { tpl, err := template.New("ent").Parse(tpl_ent) if err != nil { return err } fd_ent, err := os.OpenFile(fp_ent, os.O_CREATE|os.O_WRONLY, os.FileMode(0644)) if err != nil { return err } defer fd_ent.Close() err = tpl.Execute(fd_ent, data) if err != nil { return err } fmt.Printf("成功生成 ent 文件 %s\n", fp_ent) } // 创建 store fp_store := fp + "/store.go" if gfile.Exists(fp_store) { fmt.Printf("SKIP for store %s 存在\n", fp_store) } else { tpl, err := template.New("store").Parse(tpl_store) if err != nil { return err } fd_model, err := os.OpenFile(fp_store, os.O_CREATE|os.O_WRONLY, os.FileMode(0644)) if err != nil { return err } defer fd_model.Close() err = tpl.Execute(fd_model, data) if err != nil { return err } fmt.Printf("成功生成 store 文件 %s\n", fp_store) } return nil } } // cmd template {{{ const tpl_cmd = ` package cmds import ( "flag" "fmt" "git.hexq.cn/tiglog/golib/console" ) type {{.name}}_cmd struct { console.BaseCmd } func New{{.Name}}Cmd(cli console.IConsole) *{{.name}}_cmd { return &{{.name}}_cmd{ console.BaseCmd{ Name: "{{.name}}", Desc: "{{.desc}}", }, } } func (c *{{.name}}_cmd) Init(args []string) { if len(args) == 0 { return } name := args[0] args = args[1:] cmd := flag.NewFlagSet(name, flag.ExitOnError) switch name { case "foo": c.initFooCmd(cmd, args) } } func (c *{{.name}}_cmd) initFooCmd(cmd *flag.FlagSet, args []string) { var ( name string ) cmd.StringVar(&name, "name", "", "姓名") cmd.Parse(args) c.Action = func() error { fmt.Printf("hello %s", name) return nil } } func (c *{{.name}}_cmd) GetHelp() string { out := "{{.name}} [options]\n" out += "sub actions:\n" out += " foo hello world\n" return out } ` // }}} func (c *gen_cmd) initCmdCmd(cmd *flag.FlagSet, args []string) { var ( name string desc string ) cmd.StringVar(&name, "name", "", "cmd 名称") cmd.StringVar(&desc, "desc", "", "描述") cmd.Parse(args) c.Action = func() error { if name == "" || desc == "" { return errors.New("name 和 desc 不能为空") } var fp = "./innernal/console/cmds/" + name + "_cmd.go" if gfile.Exists(fp) { return errors.New("文件已存在,不能生成") } tpl, err := template.New("cmd").Parse(tpl_cmd) if err != nil { return err } data := map[string]string{ "name": name, "Name": strings.ToUpper(name[0:1]) + name[1:], "desc": desc, } fd, err := os.OpenFile(fp, os.O_CREATE|os.O_WRONLY, os.FileMode(0644)) if err != nil { return err } defer fd.Close() err = tpl.Execute(fd, data) if err != nil { return err } fmt.Printf("成功生成 cmd 文件 %s\n", fp) return nil } } // api template {{{ const tpl_api = ` package api import ( "git.hexq.cn/tiglog/golib/helper" "git.hexq.cn/tiglog/golib/gweb" ) type {{.name}}_api struct { } func Init{{.Name}}(app *gweb.Engine) { ap := &{{.name}}_api{} app.POST("/api/hello", ap.hello) } func (a *{{.name}}_api) hello(c *gweb.Context) { helper.RenderOk(c, "world") } ` // }}} func (c *gen_cmd) initApiCmd(cmd *flag.FlagSet, args []string) { var ( name string ) cmd.StringVar(&name, "name", "", "api 名称") cmd.Parse(args) c.Action = func() error { if name == "" { return errors.New("name 不能为空") } var fp = "./innernal/http/api/" + name + "_api.go" if gfile.Exists(fp) { return errors.New("文件已存在,不能生成") } tpl, err := template.New("api").Parse(tpl_api) if err != nil { return err } data := map[string]string{ "name": name, "Name": strings.ToUpper(name[0:1]) + name[1:], } fd, err := os.OpenFile(fp, os.O_CREATE|os.O_WRONLY, os.FileMode(0644)) if err != nil { return err } defer fd.Close() err = tpl.Execute(fd, data) if err != nil { return err } fmt.Printf("成功生成 api 文件 %s\n", fp) return nil } } func (c *gen_cmd) GetHelp() string { out := "gen [options]\n" out += "sub actions:\n" out += " model 生成 model 代码\n" out += " cmd 生成 cmd 代码\n" out += " api 生成 api 代码\n" return out }