Do not run parent node on missing child err with usageOnMissing option

Refactors usageOnMissing option to not run parent commands after
printing usage when a child node is missing.

Signed-off-by: hasheddan <georgedanielmangum@gmail.com>
This commit is contained in:
hasheddan
2020-10-04 19:27:12 -05:00
committed by Alec Thomas
parent 5b3fd5476a
commit a062611ecf
3 changed files with 40 additions and 12 deletions
+5 -11
View File
@@ -187,9 +187,6 @@ func (c *Context) Validate() error { // nolint: gocyclo
}
if err := checkMissingChildren(node); err != nil {
if c.Kong.usageOnMissing {
return c.PrintUsage(false)
}
return err
}
if err := checkMissingPositionals(positionals, node.Positional); err != nil {
@@ -628,10 +625,13 @@ func (c *Context) Run(binds ...interface{}) (err error) {
node := c.Selected()
if node == nil {
if c.Kong.usageOnMissing {
return nil
return c.PrintUsage(false)
}
return fmt.Errorf("no command selected")
}
if c.Kong.usageOnMissing && isMissingChildError(c.Error) {
return c.PrintUsage(false)
}
return c.RunNode(node, binds...)
}
@@ -700,13 +700,7 @@ func checkMissingChildren(node *Node) error {
return nil
}
if len(missing) > 5 {
missing = append(missing[:5], "...")
}
if len(missing) == 1 {
return fmt.Errorf("expected %s", missing[0])
}
return fmt.Errorf("expected one of %s", strings.Join(missing, ", "))
return newMissingChildError(missing)
}
// If we're missing any positionals and they're required, return an error.
+31
View File
@@ -1,5 +1,10 @@
package kong
import (
"fmt"
"strings"
)
// ParseError is the error type returned by Kong.Parse().
//
// It contains the parse Context that triggered the error.
@@ -10,3 +15,29 @@ type ParseError struct {
// Cause returns the original cause of the error.
func (p *ParseError) Cause() error { return p.error }
type missingChildError struct {
missing []string
}
func (m *missingChildError) Error() string {
if len(m.missing) > 5 {
m.missing = append(m.missing[:5], "...")
}
if len(m.missing) == 1 {
return fmt.Sprintf("expected %s", m.missing[0])
}
return fmt.Sprintf("expected one of %s", strings.Join(m.missing, ", "))
}
func newMissingChildError(missing []string) *missingChildError {
return &missingChildError{missing}
}
func isMissingChildError(err error) bool {
if err == nil {
return false
}
_, ok := err.(*missingChildError)
return ok
}
+4 -1
View File
@@ -219,7 +219,10 @@ func (k *Kong) Parse(args []string) (ctx *Context, err error) {
return nil, &ParseError{error: err, Context: ctx}
}
if err = ctx.Validate(); err != nil {
return nil, &ParseError{error: err, Context: ctx}
if !k.usageOnError || !isMissingChildError(err) {
return nil, &ParseError{error: err, Context: ctx}
}
ctx.Error = err
}
if err = k.applyHook(ctx, "AfterApply"); err != nil {
return nil, &ParseError{error: err, Context: ctx}