Make app help behavior consistent with commands
This commit is contained in:
parent
bab428af09
commit
9ab178d174
33
help.go
33
help.go
@ -49,13 +49,16 @@ type helpPrinterCustom func(w io.Writer, templ string, data interface{}, customF
|
|||||||
|
|
||||||
// HelpPrinter is a function that writes the help output. If not set explicitly,
|
// HelpPrinter is a function that writes the help output. If not set explicitly,
|
||||||
// this calls HelpPrinterCustom using only the default template functions.
|
// this calls HelpPrinterCustom using only the default template functions.
|
||||||
|
//
|
||||||
|
// If custom logic for printing help is required, this function can be
|
||||||
|
// overridden. If the ExtraInfo field is defined on an App, this function
|
||||||
|
// should not be modified, as HelpPrinterCustom will be used directly in order
|
||||||
|
// to capture the extra information.
|
||||||
var HelpPrinter helpPrinter = printHelp
|
var HelpPrinter helpPrinter = printHelp
|
||||||
|
|
||||||
// HelpPrinterCustom is a function that writes the help output. If not set
|
// HelpPrinterCustom is a function that writes the help output. It is used as
|
||||||
// explicitly, a default is used.
|
// the default implementation of HelpPrinter, and may be called directly if
|
||||||
//
|
// the ExtraInfo field is set on an App.
|
||||||
// The customFuncs map will be combined with a default template.FuncMap to
|
|
||||||
// allow using arbitrary functions in template rendering.
|
|
||||||
var HelpPrinterCustom helpPrinterCustom = printHelpCustom
|
var HelpPrinterCustom helpPrinterCustom = printHelpCustom
|
||||||
|
|
||||||
// VersionPrinter prints the version for the App
|
// VersionPrinter prints the version for the App
|
||||||
@ -68,20 +71,24 @@ func ShowAppHelpAndExit(c *Context, exitCode int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ShowAppHelp is an action that displays the help.
|
// ShowAppHelp is an action that displays the help.
|
||||||
func ShowAppHelp(c *Context) (err error) {
|
func ShowAppHelp(c *Context) error {
|
||||||
if c.App.CustomAppHelpTemplate == "" {
|
template := c.App.CustomAppHelpTemplate
|
||||||
HelpPrinter(c.App.Writer, AppHelpTemplate, c.App)
|
if template == "" {
|
||||||
return
|
template = AppHelpTemplate
|
||||||
}
|
}
|
||||||
customAppData := func() map[string]interface{} {
|
|
||||||
if c.App.ExtraInfo == nil {
|
if c.App.ExtraInfo == nil {
|
||||||
|
HelpPrinter(c.App.Writer, template, c.App)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
customAppData := func() map[string]interface{} {
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
"ExtraInfo": c.App.ExtraInfo,
|
"ExtraInfo": c.App.ExtraInfo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HelpPrinterCustom(c.App.Writer, c.App.CustomAppHelpTemplate, c.App, customAppData())
|
HelpPrinterCustom(c.App.Writer, template, c.App, customAppData())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,6 +249,10 @@ func ShowCommandCompletions(ctx *Context, command string) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// printHelpCustom is the default implementation of HelpPrinterCustom.
|
||||||
|
//
|
||||||
|
// The customFuncs map will be combined with a default template.FuncMap to
|
||||||
|
// allow using arbitrary functions in template rendering.
|
||||||
func printHelpCustom(out io.Writer, templ string, data interface{}, customFuncs map[string]interface{}) {
|
func printHelpCustom(out io.Writer, templ string, data interface{}, customFuncs map[string]interface{}) {
|
||||||
funcMap := template.FuncMap{
|
funcMap := template.FuncMap{
|
||||||
"join": strings.Join,
|
"join": strings.Join,
|
||||||
|
139
help_test.go
139
help_test.go
@ -295,6 +295,7 @@ func TestShowCommandHelp_HelpPrinter(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShowCommandHelp_HelpPrinterCustom(t *testing.T) {
|
func TestShowCommandHelp_HelpPrinterCustom(t *testing.T) {
|
||||||
doublecho := func(text string) string {
|
doublecho := func(text string) string {
|
||||||
return text + " " + text
|
return text + " " + text
|
||||||
@ -550,6 +551,144 @@ func TestShowAppHelp_HiddenCommand(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestShowAppHelp_HelpPrinter(t *testing.T) {
|
||||||
|
doublecho := func(text string) string {
|
||||||
|
return text + " " + text
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
template string
|
||||||
|
printer helpPrinter
|
||||||
|
wantTemplate string
|
||||||
|
wantOutput string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "standard-command",
|
||||||
|
template: "",
|
||||||
|
printer: func(w io.Writer, templ string, data interface{}) {
|
||||||
|
fmt.Fprint(w, "yo")
|
||||||
|
},
|
||||||
|
wantTemplate: AppHelpTemplate,
|
||||||
|
wantOutput: "yo",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "custom-template-command",
|
||||||
|
template: "{{doublecho .Name}}",
|
||||||
|
printer: func(w io.Writer, templ string, data interface{}) {
|
||||||
|
// Pass a custom function to ensure it gets used
|
||||||
|
fm := map[string]interface{}{"doublecho": doublecho}
|
||||||
|
printHelpCustom(w, templ, data, fm)
|
||||||
|
},
|
||||||
|
wantTemplate: "{{doublecho .Name}}",
|
||||||
|
wantOutput: "my-app my-app",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
defer func(old helpPrinter) {
|
||||||
|
HelpPrinter = old
|
||||||
|
}(HelpPrinter)
|
||||||
|
HelpPrinter = func(w io.Writer, templ string, data interface{}) {
|
||||||
|
if templ != tt.wantTemplate {
|
||||||
|
t.Errorf("want template:\n%s\ngot template:\n%s", tt.wantTemplate, templ)
|
||||||
|
}
|
||||||
|
|
||||||
|
tt.printer(w, templ, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
app := &App{
|
||||||
|
Name: "my-app",
|
||||||
|
Writer: &buf,
|
||||||
|
CustomAppHelpTemplate: tt.template,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := app.Run([]string{"my-app", "help"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
got := buf.String()
|
||||||
|
if got != tt.wantOutput {
|
||||||
|
t.Errorf("want output %q, got %q", tt.wantOutput, got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShowAppHelp_HelpPrinterCustom(t *testing.T) {
|
||||||
|
doublecho := func(text string) string {
|
||||||
|
return text + " " + text
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
template string
|
||||||
|
printer helpPrinterCustom
|
||||||
|
wantTemplate string
|
||||||
|
wantOutput string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "standard-command",
|
||||||
|
template: "",
|
||||||
|
printer: func(w io.Writer, templ string, data interface{}, fm map[string]interface{}) {
|
||||||
|
fmt.Fprint(w, "yo")
|
||||||
|
},
|
||||||
|
wantTemplate: AppHelpTemplate,
|
||||||
|
wantOutput: "yo",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "custom-template-command",
|
||||||
|
template: "{{doublecho .Name}}",
|
||||||
|
printer: func(w io.Writer, templ string, data interface{}, _ map[string]interface{}) {
|
||||||
|
// Pass a custom function to ensure it gets used
|
||||||
|
fm := map[string]interface{}{"doublecho": doublecho}
|
||||||
|
printHelpCustom(w, templ, data, fm)
|
||||||
|
},
|
||||||
|
wantTemplate: "{{doublecho .Name}}",
|
||||||
|
wantOutput: "my-app my-app",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
defer func(old helpPrinterCustom) {
|
||||||
|
HelpPrinterCustom = old
|
||||||
|
}(HelpPrinterCustom)
|
||||||
|
HelpPrinterCustom = func(w io.Writer, templ string, data interface{}, fm map[string]interface{}) {
|
||||||
|
if fm != nil {
|
||||||
|
t.Error("unexpected function map passed")
|
||||||
|
}
|
||||||
|
|
||||||
|
if templ != tt.wantTemplate {
|
||||||
|
t.Errorf("want template:\n%s\ngot template:\n%s", tt.wantTemplate, templ)
|
||||||
|
}
|
||||||
|
|
||||||
|
tt.printer(w, templ, data, fm)
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
app := &App{
|
||||||
|
Name: "my-app",
|
||||||
|
Writer: &buf,
|
||||||
|
CustomAppHelpTemplate: tt.template,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := app.Run([]string{"my-app", "help"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
got := buf.String()
|
||||||
|
if got != tt.wantOutput {
|
||||||
|
t.Errorf("want output %q, got %q", tt.wantOutput, got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestShowAppHelp_CustomAppTemplate(t *testing.T) {
|
func TestShowAppHelp_CustomAppTemplate(t *testing.T) {
|
||||||
app := &App{
|
app := &App{
|
||||||
Commands: []Command{
|
Commands: []Command{
|
||||||
|
Loading…
Reference in New Issue
Block a user