feat: 增加 gen 命令

This commit is contained in:
tiglog 2023-10-15 00:33:48 +08:00
parent 03b0c508d8
commit 73642be12c

367
console/cli_gen.go Normal file
View File

@ -0,0 +1,367 @@
//
// cli_gen.go
// Copyright (C) 2023 tiglog <me@tiglog.com>
//
// Distributed under terms of the MIT license.
//
package console
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}} <action> [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 <action> [options]\n"
out += "sub actions\n"
out += " model 生成 model 代码\n"
out += " cmd 生成 cmd 代码\n"
out += " api 生成 api 代码\n"
return out
}