Skip to content

Commit

Permalink
Adds a new hook to tweak command description at runtime
Browse files Browse the repository at this point in the history
For one feature I'm currently implementing I need to be able to tweak a command description based on some runtime information.
My main use case is to customize the description (basically rendering it as a template but with some context values that we can't provide generically).
So I ended up with this solution.

The idea is to allow one to register a hook that will be called during command help rendering to compute the command description.
  • Loading branch information
tucksaun committed Jun 10, 2024
1 parent 03d8cd7 commit 2a5f1c8
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 0 deletions.
2 changes: 2 additions & 0 deletions command.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ type Command struct {
Usage string
// A longer explanation of how the command works
Description string
// or a function responsible to render the description
DescriptionFunc DescriptionFunc
// The category the command is part of
Category string
// An action to execute before any sub-subcommands are run, but after the context is ready
Expand Down
4 changes: 4 additions & 0 deletions funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ type ActionFunc func(*Context) error
// CommandNotFoundFunc is executed if the proper command cannot be found
type CommandNotFoundFunc func(*Context, string) error

// DescriptionFunc is used by the help generation to display a description when
// its computation is intensive or needs runtime information
type DescriptionFunc func(*Command, *Application) string

// FlagStringFunc is used by the help generation to display a flag, which is
// expected to be a single line.
type FlagStringFunc func(Flag) string
4 changes: 4 additions & 0 deletions help.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ func ShowAppHelp(c *Context) error {
// ShowCommandHelp prints help for the given command
func ShowCommandHelp(ctx *Context, command string) error {
if c := ctx.App.Command(command); c != nil {
if c.DescriptionFunc != nil {
c.Description = c.DescriptionFunc(c, ctx.App)
}

HelpPrinter(ctx.App.Writer, CommandHelpTemplate, c)
return nil
}
Expand Down
25 changes: 25 additions & 0 deletions help_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,31 @@ func TestShowCommandHelp_CommandAliases(t *testing.T) {
}
}

func TestShowCommandHelp_DescriptionFunc(t *testing.T) {
app := &Application{
Commands: []*Command{
{
Name: "frobbly",
Description: "this is not my custom description",
DescriptionFunc: func(*Command, *Application) string {
return "this is my custom description"
},
Action: func(ctx *Context) error {
return nil
},
},
},
}

output := &bytes.Buffer{}
app.Writer = output
app.Run([]string{"foo", "help", "frobbly"})

if !strings.Contains(output.String(), "this is my custom description") {
t.Errorf("expected output to include result of DescriptionFunc; got: %q", output.String())
}
}

func TestShowAppHelp_HiddenCommand(t *testing.T) {
app := &Application{
Commands: []*Command{
Expand Down

0 comments on commit 2a5f1c8

Please sign in to comment.