Add HideHelpCommand
While `HideHelp` hides both `help` command and `--help` flag, `HideHelpCommand` only hides `help` command and leave `--help` flag as-is. The behavior of `HideHelp` is untouched in this commit. Fix #523 Replace #636 Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
This commit is contained in:
parent
1b7e4e00c7
commit
75e7c526bd
21
app.go
21
app.go
@ -43,8 +43,11 @@ type App struct {
|
|||||||
Flags []Flag
|
Flags []Flag
|
||||||
// Boolean to enable bash completion commands
|
// Boolean to enable bash completion commands
|
||||||
EnableBashCompletion bool
|
EnableBashCompletion bool
|
||||||
// Boolean to hide built-in help command
|
// Boolean to hide built-in help command and help flag
|
||||||
HideHelp bool
|
HideHelp bool
|
||||||
|
// Boolean to hide built-in help command but keep help flag.
|
||||||
|
// Ignored if HideHelp is true.
|
||||||
|
HideHelpCommand bool
|
||||||
// Boolean to hide built-in version flag and the VERSION section of help
|
// Boolean to hide built-in version flag and the VERSION section of help
|
||||||
HideVersion bool
|
HideVersion bool
|
||||||
// categories contains the categorized commands and is populated on app startup
|
// categories contains the categorized commands and is populated on app startup
|
||||||
@ -170,7 +173,9 @@ func (a *App) Setup() {
|
|||||||
a.Commands = newCommands
|
a.Commands = newCommands
|
||||||
|
|
||||||
if a.Command(helpCommand.Name) == nil && !a.HideHelp {
|
if a.Command(helpCommand.Name) == nil && !a.HideHelp {
|
||||||
a.appendCommand(helpCommand)
|
if !a.HideHelpCommand {
|
||||||
|
a.appendCommand(helpCommand)
|
||||||
|
}
|
||||||
|
|
||||||
if HelpFlag != nil {
|
if HelpFlag != nil {
|
||||||
a.appendFlag(HelpFlag)
|
a.appendFlag(HelpFlag)
|
||||||
@ -328,19 +333,9 @@ func (a *App) RunAndExitOnError() {
|
|||||||
// RunAsSubcommand invokes the subcommand given the context, parses ctx.Args() to
|
// RunAsSubcommand invokes the subcommand given the context, parses ctx.Args() to
|
||||||
// generate command-specific flags
|
// generate command-specific flags
|
||||||
func (a *App) RunAsSubcommand(ctx *Context) (err error) {
|
func (a *App) RunAsSubcommand(ctx *Context) (err error) {
|
||||||
|
// Setup also handles HideHelp and HideHelpCommand
|
||||||
a.Setup()
|
a.Setup()
|
||||||
|
|
||||||
// append help to commands
|
|
||||||
if len(a.Commands) > 0 {
|
|
||||||
if a.Command(helpCommand.Name) == nil && !a.HideHelp {
|
|
||||||
a.appendCommand(helpCommand)
|
|
||||||
|
|
||||||
if HelpFlag != nil {
|
|
||||||
a.appendFlag(HelpFlag)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var newCmds []*Command
|
var newCmds []*Command
|
||||||
for _, c := range a.Commands {
|
for _, c := range a.Commands {
|
||||||
if c.HelpName == "" {
|
if c.HelpName == "" {
|
||||||
|
@ -41,8 +41,11 @@ type Command struct {
|
|||||||
Flags []Flag
|
Flags []Flag
|
||||||
// Treat all flags as normal arguments if true
|
// Treat all flags as normal arguments if true
|
||||||
SkipFlagParsing bool
|
SkipFlagParsing bool
|
||||||
// Boolean to hide built-in help command
|
// Boolean to hide built-in help command and help flag
|
||||||
HideHelp bool
|
HideHelp bool
|
||||||
|
// Boolean to hide built-in help command but keep help flag
|
||||||
|
// Ignored if HideHelp is true.
|
||||||
|
HideHelpCommand bool
|
||||||
// Boolean to hide this command from help or completion
|
// Boolean to hide this command from help or completion
|
||||||
Hidden bool
|
Hidden bool
|
||||||
// Boolean to enable short-option handling so user can combine several
|
// Boolean to enable short-option handling so user can combine several
|
||||||
@ -236,6 +239,7 @@ func (c *Command) startApp(ctx *Context) error {
|
|||||||
app.Commands = c.Subcommands
|
app.Commands = c.Subcommands
|
||||||
app.Flags = c.Flags
|
app.Flags = c.Flags
|
||||||
app.HideHelp = c.HideHelp
|
app.HideHelp = c.HideHelp
|
||||||
|
app.HideHelpCommand = c.HideHelpCommand
|
||||||
|
|
||||||
app.Version = ctx.App.Version
|
app.Version = ctx.App.Version
|
||||||
app.HideVersion = ctx.App.HideVersion
|
app.HideVersion = ctx.App.HideVersion
|
||||||
|
2
flag.go
2
flag.go
@ -36,7 +36,7 @@ var VersionFlag Flag = &BoolFlag{
|
|||||||
|
|
||||||
// HelpFlag prints the help for all commands and subcommands.
|
// HelpFlag prints the help for all commands and subcommands.
|
||||||
// Set to nil to disable the flag. The subcommand
|
// Set to nil to disable the flag. The subcommand
|
||||||
// will still be added unless HideHelp is set to true.
|
// will still be added unless HideHelp or HideHelpCommand is set to true.
|
||||||
var HelpFlag Flag = &BoolFlag{
|
var HelpFlag Flag = &BoolFlag{
|
||||||
Name: "help",
|
Name: "help",
|
||||||
Aliases: []string{"h"},
|
Aliases: []string{"h"},
|
||||||
|
145
help_test.go
145
help_test.go
@ -5,6 +5,7 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@ -762,3 +763,147 @@ VERSION:
|
|||||||
t.Errorf("expected output to include \"VERSION:, 2.0.0\"; got: %q", output.String())
|
t.Errorf("expected output to include \"VERSION:, 2.0.0\"; got: %q", output.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHideHelpCommand(t *testing.T) {
|
||||||
|
app := &App{
|
||||||
|
HideHelpCommand: true,
|
||||||
|
Writer: ioutil.Discard,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := app.Run([]string{"foo", "help"})
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expected a non-nil error")
|
||||||
|
}
|
||||||
|
if !strings.Contains(err.Error(), "No help topic for 'help'") {
|
||||||
|
t.Errorf("Run returned unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = app.Run([]string{"foo", "--help"})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Run returned unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHideHelpCommand_False(t *testing.T) {
|
||||||
|
app := &App{
|
||||||
|
HideHelpCommand: false,
|
||||||
|
Writer: ioutil.Discard,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := app.Run([]string{"foo", "help"})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Run returned unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = app.Run([]string{"foo", "--help"})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Run returned unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHideHelpCommand_WithHideHelp(t *testing.T) {
|
||||||
|
app := &App{
|
||||||
|
HideHelp: true, // effective (hides both command and flag)
|
||||||
|
HideHelpCommand: true, // ignored
|
||||||
|
Writer: ioutil.Discard,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := app.Run([]string{"foo", "help"})
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expected a non-nil error")
|
||||||
|
}
|
||||||
|
if !strings.Contains(err.Error(), "No help topic for 'help'") {
|
||||||
|
t.Errorf("Run returned unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = app.Run([]string{"foo", "--help"})
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expected a non-nil error")
|
||||||
|
}
|
||||||
|
if !strings.Contains(err.Error(), "flag: help requested") {
|
||||||
|
t.Errorf("Run returned unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newContextFromStringSlice(ss []string) *Context {
|
||||||
|
set := flag.NewFlagSet("", flag.ContinueOnError)
|
||||||
|
_ = set.Parse(ss)
|
||||||
|
return &Context{flagSet: set}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHideHelpCommand_RunAsSubcommand(t *testing.T) {
|
||||||
|
app := &App{
|
||||||
|
HideHelpCommand: true,
|
||||||
|
Writer: ioutil.Discard,
|
||||||
|
Commands: []*Command{
|
||||||
|
{
|
||||||
|
Name: "dummy",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := app.RunAsSubcommand(newContextFromStringSlice([]string{"", "help"}))
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expected a non-nil error")
|
||||||
|
}
|
||||||
|
if !strings.Contains(err.Error(), "No help topic for 'help'") {
|
||||||
|
t.Errorf("Run returned unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = app.RunAsSubcommand(newContextFromStringSlice([]string{"", "--help"}))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Run returned unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHideHelpCommand_RunAsSubcommand_False(t *testing.T) {
|
||||||
|
app := &App{
|
||||||
|
HideHelpCommand: false,
|
||||||
|
Writer: ioutil.Discard,
|
||||||
|
Commands: []*Command{
|
||||||
|
{
|
||||||
|
Name: "dummy",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := app.RunAsSubcommand(newContextFromStringSlice([]string{"", "help"}))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Run returned unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = app.RunAsSubcommand(newContextFromStringSlice([]string{"", "--help"}))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Run returned unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHideHelpCommand_WithSubcommands(t *testing.T) {
|
||||||
|
app := &App{
|
||||||
|
Writer: ioutil.Discard,
|
||||||
|
Commands: []*Command{
|
||||||
|
{
|
||||||
|
Name: "dummy",
|
||||||
|
Subcommands: []*Command{
|
||||||
|
{
|
||||||
|
Name: "dummy2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
HideHelpCommand: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := app.Run([]string{"foo", "dummy", "help"})
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expected a non-nil error")
|
||||||
|
}
|
||||||
|
if !strings.Contains(err.Error(), "No help topic for 'help'") {
|
||||||
|
t.Errorf("Run returned unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = app.Run([]string{"foo", "dummy", "--help"})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Run returned unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user