mirror of
https://github.com/spf13/cobra
synced 2025-04-27 09:07:19 +00:00
Merge 9fbba57c76
into 09d5664f34
This commit is contained in:
commit
1fd0dd1361
2 changed files with 207 additions and 6 deletions
22
command.go
22
command.go
|
@ -469,9 +469,10 @@ func (c *Command) HelpFunc() func(*Command, []string) {
|
|||
}
|
||||
}
|
||||
|
||||
// Help puts out the help for the command.
|
||||
// Used when a user calls help [command].
|
||||
// Can be defined by user by overriding HelpFunc.
|
||||
// Help invokes the HelpFunc without arguments.
|
||||
// Kept for backwards compatibility.
|
||||
// Can be a simple way to trigger the help
|
||||
// if arguments are not needed.
|
||||
func (c *Command) Help() error {
|
||||
c.HelpFunc()(c, []string{})
|
||||
return nil
|
||||
|
@ -1122,7 +1123,16 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
|
|||
// Always show help if requested, even if SilenceErrors is in
|
||||
// effect
|
||||
if errors.Is(err, flag.ErrHelp) {
|
||||
cmd.HelpFunc()(cmd, args)
|
||||
// The call to execute() above has parsed the flags.
|
||||
// We therefore only pass the remaining arguments to the help function.
|
||||
remainingArgs := cmd.Flags().Args()
|
||||
if cmd.DisableFlagParsing {
|
||||
// For commands that have DisableFlagParsing == true, the flag parsing
|
||||
// was not done and cmd.Flags().Args() is not filled. We therefore
|
||||
// use the full set of arguments, which include flags.
|
||||
remainingArgs = flags
|
||||
}
|
||||
cmd.HelpFunc()(cmd, remainingArgs)
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
|
@ -1263,14 +1273,14 @@ Simply type ` + c.DisplayName() + ` help [path to command] for full details.`,
|
|||
return completions, ShellCompDirectiveNoFileComp
|
||||
},
|
||||
Run: func(c *Command, args []string) {
|
||||
cmd, _, e := c.Root().Find(args)
|
||||
cmd, remainingArgs, e := c.Root().Find(args)
|
||||
if cmd == nil || e != nil {
|
||||
c.Printf("Unknown help topic %#q\n", args)
|
||||
CheckErr(c.Root().Usage())
|
||||
} else {
|
||||
cmd.InitDefaultHelpFlag() // make possible 'help' flag to be shown
|
||||
cmd.InitDefaultVersionFlag() // make possible 'version' flag to be shown
|
||||
CheckErr(cmd.Help())
|
||||
cmd.HelpFunc()(cmd, remainingArgs)
|
||||
}
|
||||
},
|
||||
GroupID: c.helpCommandGroupID,
|
||||
|
|
191
command_test.go
191
command_test.go
|
@ -1083,6 +1083,197 @@ func TestHelpExecutedOnNonRunnableChild(t *testing.T) {
|
|||
checkStringContains(t, output, childCmd.Long)
|
||||
}
|
||||
|
||||
type overridingHelp struct {
|
||||
expectedCmdName string
|
||||
expectedArgs []string
|
||||
|
||||
helpCalled bool
|
||||
err error
|
||||
}
|
||||
|
||||
func (o *overridingHelp) helpFunc() func(c *Command, args []string) {
|
||||
return func(c *Command, args []string) {
|
||||
o.helpCalled = true
|
||||
if c.Name() != o.expectedCmdName {
|
||||
o.err = fmt.Errorf("Expected command name: %q, got %q", o.expectedCmdName, c.Name())
|
||||
return
|
||||
}
|
||||
|
||||
if len(args) != len(o.expectedArgs) {
|
||||
o.err = fmt.Errorf("Expected args %v, got %v", o.expectedArgs, args)
|
||||
return
|
||||
}
|
||||
|
||||
for i, arg := range o.expectedArgs {
|
||||
if args[i] != arg {
|
||||
o.err = fmt.Errorf("Expected args %v, got %v", o.expectedArgs, args)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (o *overridingHelp) checkError() error {
|
||||
if o.err != nil {
|
||||
return o.err
|
||||
}
|
||||
if !o.helpCalled {
|
||||
return fmt.Errorf("Overridden help function not called")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestHelpOverrideOnRoot(t *testing.T) {
|
||||
rootCmd := &Command{Use: "root"}
|
||||
|
||||
override := overridingHelp{
|
||||
expectedCmdName: rootCmd.Name(),
|
||||
expectedArgs: []string{"arg1", "arg2"},
|
||||
}
|
||||
rootCmd.SetHelpFunc(override.helpFunc())
|
||||
|
||||
_, err := executeCommand(rootCmd, "arg1", "arg2", "--help")
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error executing command: %v", err)
|
||||
}
|
||||
|
||||
if err = override.checkError(); err != nil {
|
||||
t.Errorf("Unexpected error from help function: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelpOverrideOnChild(t *testing.T) {
|
||||
rootCmd := &Command{Use: "root"}
|
||||
subCmd := &Command{Use: "child"}
|
||||
rootCmd.AddCommand(subCmd)
|
||||
|
||||
override := overridingHelp{
|
||||
expectedCmdName: subCmd.Name(),
|
||||
expectedArgs: []string{"arg1", "arg2"},
|
||||
}
|
||||
subCmd.SetHelpFunc(override.helpFunc())
|
||||
|
||||
_, err := executeCommand(rootCmd, "child", "arg1", "arg2", "--help")
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error executing command: %v", err)
|
||||
}
|
||||
|
||||
if err = override.checkError(); err != nil {
|
||||
t.Errorf("Unexpected error from help function: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelpOverrideOnRootWithChild(t *testing.T) {
|
||||
rootCmd := &Command{Use: "root"}
|
||||
subCmd := &Command{Use: "child"}
|
||||
rootCmd.AddCommand(subCmd)
|
||||
|
||||
override := overridingHelp{
|
||||
expectedCmdName: subCmd.Name(),
|
||||
expectedArgs: []string{"arg1", "arg2"},
|
||||
}
|
||||
rootCmd.SetHelpFunc(override.helpFunc())
|
||||
|
||||
_, err := executeCommand(rootCmd, "child", "arg1", "arg2", "--help")
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error executing command: %v", err)
|
||||
}
|
||||
|
||||
if err = override.checkError(); err != nil {
|
||||
t.Errorf("Unexpected error from help function: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelpOverrideOnRootWithChildAndFlags(t *testing.T) {
|
||||
rootCmd := &Command{Use: "root"}
|
||||
subCmd := &Command{Use: "child"}
|
||||
rootCmd.AddCommand(subCmd)
|
||||
|
||||
var myFlag bool
|
||||
subCmd.Flags().BoolVar(&myFlag, "myflag", false, "")
|
||||
|
||||
override := overridingHelp{
|
||||
expectedCmdName: subCmd.Name(),
|
||||
expectedArgs: []string{"arg1", "arg2"},
|
||||
}
|
||||
rootCmd.SetHelpFunc(override.helpFunc())
|
||||
|
||||
_, err := executeCommand(rootCmd, "child", "arg1", "--myflag", "arg2", "--help")
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error executing command: %v", err)
|
||||
}
|
||||
|
||||
if err = override.checkError(); err != nil {
|
||||
t.Errorf("Unexpected error from help function: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelpOverrideOnRootWithChildAndFlagsButParsingDisabled(t *testing.T) {
|
||||
rootCmd := &Command{Use: "root"}
|
||||
subCmd := &Command{Use: "child", DisableFlagParsing: true}
|
||||
rootCmd.AddCommand(subCmd)
|
||||
|
||||
var myFlag bool
|
||||
subCmd.Flags().BoolVar(&myFlag, "myflag", false, "")
|
||||
|
||||
override := overridingHelp{
|
||||
expectedCmdName: subCmd.Name(),
|
||||
expectedArgs: []string{"arg1", "--myflag", "arg2", "--help"},
|
||||
}
|
||||
rootCmd.SetHelpFunc(override.helpFunc())
|
||||
|
||||
_, err := executeCommand(rootCmd, "child", "arg1", "--myflag", "arg2", "--help")
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error executing command: %v", err)
|
||||
}
|
||||
|
||||
if err = override.checkError(); err != nil {
|
||||
t.Errorf("Unexpected error from help function: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelpCommandOverrideOnChild(t *testing.T) {
|
||||
rootCmd := &Command{Use: "root"}
|
||||
subCmd := &Command{Use: "child"}
|
||||
rootCmd.AddCommand(subCmd)
|
||||
|
||||
override := overridingHelp{
|
||||
expectedCmdName: subCmd.Name(),
|
||||
expectedArgs: []string{"arg1", "arg2"},
|
||||
}
|
||||
subCmd.SetHelpFunc(override.helpFunc())
|
||||
|
||||
_, err := executeCommand(rootCmd, "help", "child", "arg1", "arg2")
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error executing command: %v", err)
|
||||
}
|
||||
|
||||
if err = override.checkError(); err != nil {
|
||||
t.Errorf("Unexpected error from help function: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelpCommandOverrideOnRootWithChild(t *testing.T) {
|
||||
rootCmd := &Command{Use: "root"}
|
||||
subCmd := &Command{Use: "child"}
|
||||
rootCmd.AddCommand(subCmd)
|
||||
|
||||
override := overridingHelp{
|
||||
expectedCmdName: subCmd.Name(),
|
||||
expectedArgs: []string{"arg1", "arg2"},
|
||||
}
|
||||
rootCmd.SetHelpFunc(override.helpFunc())
|
||||
|
||||
_, err := executeCommand(rootCmd, "help", "child", "arg1", "arg2")
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error executing command: %v", err)
|
||||
}
|
||||
|
||||
if err = override.checkError(); err != nil {
|
||||
t.Errorf("Unexpected error from help function: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVersionFlagExecuted(t *testing.T) {
|
||||
rootCmd := &Command{Use: "root", Version: "1.0.0", Run: emptyRun}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue