1 Star 0 Fork 1

yss930819/gf-ex

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
command.go 4.37 KB
一键复制 编辑 原始数据 按行查看 历史
package yscmd
import (
"context"
"fmt"
"gitee.com/kmyss/gf-ex/ysbuild"
"gitee.com/kmyss/gf-ex/yslog"
"github.com/gogf/gf/v2/container/gmap"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gconv"
)
type Command struct {
Use string // 命令名称
Short string // 命令短描述
Long string // 命令长描述
Example string // 命令使用案例
Note string // 命令的详细说明
Run func(*Command)
Help func(*Command)
ctx context.Context // 链式记录使用
parent *Command // 父命令
commands *gmap.ListMap // 子命令
flags *gmap.ListMap // 标签
maxCommandLen int // 辅助记录命令长度
maxFlagLen int // 辅助记录flag的最大值
}
func (c *Command) SetContext(ctx context.Context) {
c.ctx = ctx
}
func (c *Command) Context() context.Context {
return c.ctx
}
func (c *Command) ShowHelp() {
if !g.IsEmpty(c.Help) {
c.Help(c)
} else {
yslog.Warningf("%s 命令没有帮助信息", c.Use)
}
}
func (c *Command) PrintHelp() {
yslog.Print(c.GetHelp())
}
// GetHelp 使用模板创建默认的帮助命令
func (c *Command) GetHelp() string {
out := ""
out += c.descriptionInfo()
out += c.useInfo()
out += c.commandsInfo()
out += c.flagsInfo()
out += c.exampleInfo()
out += c.noteInfo()
return out
}
func (c *Command) descriptionInfo() string {
if g.IsEmpty(c.Long) {
return ""
} else {
return fmt.Sprintf(`
介绍:%s`, c.Long)
}
}
func (c *Command) useInfo() string {
appName := c.Use
if g.IsEmpty(c.Use) && g.IsEmpty(c.parent) {
appName = ysbuild.APPName
}
parents := c.findParents()
cmd := ""
if !g.IsEmpty(parents) {
cmd += parents + " "
}
cmd += appName
return fmt.Sprintf(`
使用:
%s [命令] [选项]
`, cmd)
}
func (c *Command) findParents() string {
out := ""
if !g.IsEmpty(c.parent) {
_tmp := c.parent.findParents()
if len(_tmp) > 0 {
out += _tmp + " "
}
out += c.parent.Use
}
return out
}
func (c *Command) commandsInfo() string {
if c.commands.IsEmpty() {
return ""
} else {
out := "\n命令:"
for _, v := range c.commands.Values() {
command := v.(*Command)
out += "\n" + command.getCommandInfo(c.maxCommandLen)
}
return out + "\n"
}
}
func (c *Command) getCommandInfo(commandLen int) string {
fmtStr := ` %-` + gconv.String(commandLen) + `s %s`
return fmt.Sprintf(fmtStr, c.Use, c.Short)
}
func (c *Command) flagsInfo() string {
if c.flags.IsEmpty() {
return ""
} else {
out := "\n选项:"
for _, v := range c.flags.Values() {
flag := v.(*Flag)
out += "\n" + flag.getFlagInfo() + "\n"
}
return out
}
}
func (c *Command) exampleInfo() string {
if g.IsEmpty(c.Example) {
return ""
} else {
return fmt.Sprintf(`
样例:%s`, c.Example)
}
}
func (c *Command) noteInfo() string {
if g.IsEmpty(c.Note) {
return ""
} else {
return fmt.Sprintf(`
说明:%s`, c.Note)
}
}
// Exec 执行命令的 Run 函数
func (c *Command) Exec(ctx context.Context) {
c.ctx = ctx
if g.IsEmpty(c.Run) {
yslog.Fatal("没有可执行的函数!")
} else {
c.Run(c)
}
}
// RunChildCmd 运行子命令,<cmdUse> 表示字命令的字符.
// 当 <cmdUse> 为空时, 判断命令是否可以执行shell 可以则执行
// 当 <cmdUse> 不存在时, 显示当前命令的帮助信息
// <cmdUse> 直接执行
func (c *Command) RunChildCmd(cmdUse string) {
// 命令为空
if g.IsEmpty(cmdUse) {
if c.commands.Contains(CmdShellUse) {
yslog.Warning("未输入后续命令自动进入 shell 模式")
c.commands.Get(CmdShellUse).(*Command).Exec(c.ctx)
} else {
yslog.Error("请输入后续命令")
c.ShowHelp()
}
return
}
// 命令不存在
if !c.commands.Contains(cmdUse) {
yslog.Error("没有命令: ", cmdUse)
c.ShowHelp()
return
}
get := c.commands.Get(cmdUse)
get.(*Command).Exec(c.ctx)
}
func (c *Command) AddCommand(cmd *Command) bool {
if len(cmd.Use) > c.maxCommandLen {
c.maxCommandLen = len(cmd.Use)
}
cmd.parent = c
return c.commands.SetIfNotExist(cmd.Use, cmd)
}
func (c *Command) AddFlag(f *Flag) bool {
key := ""
if !g.IsEmpty(f.ConfigKey()) {
key = f.ConfigKey()
} else if !g.IsEmpty(f.LongKey()) {
key = f.LongKey()
} else if !g.IsEmpty(f.ShortKey()) {
key = f.ShortKey()
} else {
return false
}
return c.flags.SetIfNotExist(key, f)
}
func (c *Command) Parent() *Command {
return c.parent
}
func (c *Command) Child(use string) *Command {
return c.commands.Get(use).(*Command)
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/kmyss/gf-ex.git
git@gitee.com:kmyss/gf-ex.git
kmyss
gf-ex
gf-ex
v1.0.2

搜索帮助