Return an error in the case of unrunnable subcommand
* credit to @chriswhelix for initial commit
This commit is contained in:
		
				
					committed by
					
						
						Albert Nigmatzianov
					
				
			
			
				
	
			
			
			
						parent
						
							9552679939
						
					
				
				
					commit
					9334a46bd6
				
			
							
								
								
									
										16
									
								
								command.go
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								command.go
									
									
									
									
									
								
							@ -17,6 +17,7 @@ package cobra
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
@ -27,6 +28,9 @@ import (
 | 
				
			|||||||
	flag "github.com/spf13/pflag"
 | 
						flag "github.com/spf13/pflag"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NotRunnable defines subcommand error
 | 
				
			||||||
 | 
					var NotRunnable = errors.New("subcommand is required")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// FParseErrWhitelist configures Flag parse errors to be ignored
 | 
					// FParseErrWhitelist configures Flag parse errors to be ignored
 | 
				
			||||||
type FParseErrWhitelist flag.ParseErrorsWhitelist
 | 
					type FParseErrWhitelist flag.ParseErrorsWhitelist
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -369,7 +373,7 @@ func (c *Command) HelpFunc() func(*Command, []string) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return func(c *Command, a []string) {
 | 
						return func(c *Command, a []string) {
 | 
				
			||||||
		c.mergePersistentFlags()
 | 
							c.mergePersistentFlags()
 | 
				
			||||||
		err := tmpl(c.OutOrStdout(), c.HelpTemplate(), c)
 | 
							err := tmpl(c.OutOrStderr(), c.HelpTemplate(), c)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			c.Println(err)
 | 
								c.Println(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -786,7 +790,7 @@ func (c *Command) execute(a []string) (err error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !c.Runnable() {
 | 
						if !c.Runnable() {
 | 
				
			||||||
		return flag.ErrHelp
 | 
							return NotRunnable
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c.preRun()
 | 
						c.preRun()
 | 
				
			||||||
@ -920,6 +924,14 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
 | 
				
			|||||||
			return cmd, nil
 | 
								return cmd, nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// If command wasn't runnable, show full help, but do return the error.
 | 
				
			||||||
 | 
							// This will result in apps by default returning a non-success exit code, but also gives them the option to
 | 
				
			||||||
 | 
							// handle specially.
 | 
				
			||||||
 | 
							if err == NotRunnable {
 | 
				
			||||||
 | 
								cmd.HelpFunc()(cmd, args)
 | 
				
			||||||
 | 
								return cmd, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// If root command has SilentErrors flagged,
 | 
							// If root command has SilentErrors flagged,
 | 
				
			||||||
		// all subcommands should respect it
 | 
							// all subcommands should respect it
 | 
				
			||||||
		if !cmd.SilenceErrors && !c.SilenceErrors {
 | 
							if !cmd.SilenceErrors && !c.SilenceErrors {
 | 
				
			||||||
 | 
				
			|||||||
@ -836,8 +836,8 @@ func TestHelpExecutedOnNonRunnableChild(t *testing.T) {
 | 
				
			|||||||
	rootCmd.AddCommand(childCmd)
 | 
						rootCmd.AddCommand(childCmd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	output, err := executeCommand(rootCmd, "child")
 | 
						output, err := executeCommand(rootCmd, "child")
 | 
				
			||||||
	if err != nil {
 | 
						if err != NotRunnable {
 | 
				
			||||||
		t.Errorf("Unexpected error: %v", err)
 | 
							t.Errorf("Expected error")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	checkStringContains(t, output, childCmd.Long)
 | 
						checkStringContains(t, output, childCmd.Long)
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user