diff --git a/internal/engine/command/command.go b/internal/engine/command/command.go index 0d4b3656..03dc9f0e 100644 --- a/internal/engine/command/command.go +++ b/internal/engine/command/command.go @@ -8,6 +8,7 @@ import ( "github.com/pagu-project/pagu/internal/entity" "github.com/pagu-project/pagu/internal/version" + "github.com/pagu-project/pagu/pkg/log" "github.com/pagu-project/pagu/pkg/utils" ) @@ -21,11 +22,6 @@ const errorTemplate = ` {{.err}} ` -const aboutTemplate = ` -**About pagu** -version : {{.version}} -` - var ( TargetMaskMainnet = 1 TargetMaskTestnet = 2 @@ -126,7 +122,7 @@ func (cmd *Command) RenderFailedTemplateF(reason string, a ...any) CommandResult } func (cmd *Command) RenderFailedTemplate(reason string) CommandResult { - msg, _ := cmd.executeTemplate(failedTemplate, map[string]any{"reason": reason}) + msg := cmd.executeTemplate(failedTemplate, map[string]any{"reason": reason}) return CommandResult{ Title: fmt.Sprintf("%v %v", cmd.Name, cmd.Emoji), @@ -136,7 +132,7 @@ func (cmd *Command) RenderFailedTemplate(reason string) CommandResult { } func (cmd *Command) RenderErrorTemplate(err error) CommandResult { - msg, _ := cmd.executeTemplate(errorTemplate, map[string]any{"err": err}) + msg := cmd.executeTemplate(errorTemplate, map[string]any{"err": err}) return CommandResult{ Title: fmt.Sprintf("%v %v", cmd.Name, cmd.Emoji), @@ -158,10 +154,7 @@ func (cmd *Command) RenderResultTemplate(keyvals ...any) CommandResult { data[key] = val } - msg, err := cmd.executeTemplate(cmd.ResultTemplate, data) - if err != nil { - return cmd.RenderErrorTemplate(err) - } + msg := cmd.executeTemplate(cmd.ResultTemplate, data) return CommandResult{ Title: fmt.Sprintf("%v %v", cmd.Name, cmd.Emoji), @@ -170,16 +163,29 @@ func (cmd *Command) RenderResultTemplate(keyvals ...any) CommandResult { } } -func (*Command) executeTemplate(templateContent string, data map[string]any) (string, error) { - tmpl, _ := template.New("template").Parse(templateContent) +func (*Command) executeTemplate(templateContent string, data map[string]any) string { + funcMap := template.FuncMap{ + "fixed": func(width int, s string) string { + if len(s) > width { + return s[:width] + } + + return s + strings.Repeat(" ", width-len(s)) + }, + } + + tmpl, err := template.New("template").Funcs(funcMap).Parse(templateContent) + if err != nil { + log.Error("unable to parse template", "error", err) + } var bldr strings.Builder - err := tmpl.Execute(&bldr, data) + err = tmpl.Execute(&bldr, data) if err != nil { - return "", err + log.Error("unable to parse template", "error", err) } - return strings.TrimSpace(bldr.String()), nil + return strings.TrimSpace(bldr.String()) } // Deprecated: Use RenderResultTemplate. @@ -215,10 +221,25 @@ func (cmd *Command) ErrorResult(err error) CommandResult { return cmd.FailedResultF("An error occurred: %v", err.Error()) } -func (cmd *Command) HelpResult() CommandResult { +func (cmd *Command) RenderHelpTemplate() CommandResult { + const helpCommandTemplate = ` +{{.cmd.Help}} + +**Usage:** + {{.cmd.Name}} [subcommand] + +**Available subcommands:** + {{- range .cmd.SubCommands }} +
{{.Name | fixed 15 }}{{.Emoji}} {{.Help}} + {{- end}} + +Use "{{.cmd.Name}} help --subcommand=[subcommand]" for more information about a subcommand. +` + msg := cmd.executeTemplate(helpCommandTemplate, map[string]any{"cmd": cmd}) + return CommandResult{ - Title: fmt.Sprintf("%v %v", cmd.Help, cmd.Emoji), - Message: cmd.HelpMessage(), + Title: fmt.Sprintf("%v %v", cmd.Name, cmd.Emoji), + Message: msg, Successful: false, } } @@ -231,16 +252,6 @@ func (cmd *Command) HasSubCommand() bool { return len(cmd.SubCommands) > 0 && cmd.SubCommands != nil } -func (cmd *Command) HelpMessage() string { - help := cmd.Help - help += "\n\nAvailable commands:\n" - for _, sc := range cmd.SubCommands { - help += fmt.Sprintf("- **%-12s**: %s\n", sc.Name, sc.Help) - } - - return help -} - func (cmd *Command) AddSubCommand(subCmd *Command) { if subCmd == nil { return @@ -260,7 +271,7 @@ func (cmd *Command) AddHelpSubCommand() { AppIDs: entity.AllAppIDs(), TargetFlag: TargetMaskAll, Handler: func(_ *entity.User, _ *Command, _ map[string]string) CommandResult { - return cmd.SuccessfulResult(cmd.HelpMessage()) + return cmd.RenderHelpTemplate() }, } @@ -268,6 +279,12 @@ func (cmd *Command) AddHelpSubCommand() { } func (cmd *Command) AddAboutSubCommand() { + const aboutTemplate = ` +## About Pagu + +Version : {{.version}} +` + cmd.ResultTemplate = aboutTemplate aboutCmd := &Command{ Name: "about", diff --git a/internal/engine/command/crowdfund/crowdfund.gen.go b/internal/engine/command/crowdfund/crowdfund.gen.go index 53283510..52cb0d51 100644 --- a/internal/engine/command/crowdfund/crowdfund.gen.go +++ b/internal/engine/command/crowdfund/crowdfund.gen.go @@ -108,6 +108,7 @@ func (c *CrowdfundCmd) buildSubCmds() *crowdfundSubCmds { func (c *CrowdfundCmd) buildCrowdfundCommand() *command.Command { crowdfundCmd := &command.Command{ + Emoji: "🤝", Name: "crowdfund", Help: "Commands for managing crowdfunding campaigns", SubCommands: make([]*command.Command, 0), diff --git a/internal/engine/command/crowdfund/crowdfund.yml b/internal/engine/command/crowdfund/crowdfund.yml index fea723f9..297fd037 100644 --- a/internal/engine/command/crowdfund/crowdfund.yml +++ b/internal/engine/command/crowdfund/crowdfund.yml @@ -1,4 +1,5 @@ --- +emoji: 🤝 name: crowdfund help: Commands for managing crowdfunding campaigns sub_commands: diff --git a/internal/engine/command/market/market.gen.go b/internal/engine/command/market/market.gen.go index e2bd1d2c..66b13e5d 100644 --- a/internal/engine/command/market/market.gen.go +++ b/internal/engine/command/market/market.gen.go @@ -24,6 +24,7 @@ func (c *MarketCmd) buildSubCmds() *marketSubCmds { func (c *MarketCmd) buildMarketCommand() *command.Command { marketCmd := &command.Command{ + Emoji: "📈", Name: "market", Help: "Commands for managing market", SubCommands: make([]*command.Command, 0), diff --git a/internal/engine/command/market/market.yml b/internal/engine/command/market/market.yml index 8c602a3c..33bc0e7b 100644 --- a/internal/engine/command/market/market.yml +++ b/internal/engine/command/market/market.yml @@ -1,4 +1,5 @@ --- +emoji: 📈 name: market help: Commands for managing market sub_commands: diff --git a/internal/engine/engine.go b/internal/engine/engine.go index de896754..cd28a516 100644 --- a/internal/engine/engine.go +++ b/internal/engine/engine.go @@ -136,7 +136,7 @@ func newBotEngine(ctx context.Context, rootCmd := &command.Command{ Emoji: "🤖", Name: "pagu", - Help: "Root Command", + Help: "", AppIDs: entity.AllAppIDs(), SubCommands: make([]*command.Command, 0), } @@ -281,7 +281,7 @@ func (be *BotEngine) executeCommand( } if cmd.Handler == nil { - return cmd.HelpResult() + return cmd.RenderHelpTemplate() } caller, err := be.GetUser(appID, callerID) diff --git a/internal/generator/command.tmpl b/internal/generator/command.tmpl index 9fa27c87..94978069 100644 --- a/internal/generator/command.tmpl +++ b/internal/generator/command.tmpl @@ -59,6 +59,9 @@ func (c *{{.Name | title}}Cmd) buildSubCmds() *{{.Name}}SubCmds { func (c *{{.Name | title}}Cmd) build{{.Name | title}}Command() *command.Command { {{.Name}}Cmd := &command.Command{ + {{- if .Emoji }} + Emoji: "{{.Emoji}}", + {{- end }} Name: "{{.Name}}", Help: "{{.Help}}", SubCommands: make([]*command.Command, 0),