golib/gconsole/cli_gen.go

368 lines
7.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// cli_gen.go
// Copyright (C) 2023 tiglog <me@tiglog.com>
//
// 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}} <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
}