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:
+5
-11
@@ -187,9 +187,6 @@ func (c *Context) Validate() error { // nolint: gocyclo
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := checkMissingChildren(node); err != nil {
|
if err := checkMissingChildren(node); err != nil {
|
||||||
if c.Kong.usageOnMissing {
|
|
||||||
return c.PrintUsage(false)
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := checkMissingPositionals(positionals, node.Positional); err != nil {
|
if err := checkMissingPositionals(positionals, node.Positional); err != nil {
|
||||||
@@ -628,10 +625,13 @@ func (c *Context) Run(binds ...interface{}) (err error) {
|
|||||||
node := c.Selected()
|
node := c.Selected()
|
||||||
if node == nil {
|
if node == nil {
|
||||||
if c.Kong.usageOnMissing {
|
if c.Kong.usageOnMissing {
|
||||||
return nil
|
return c.PrintUsage(false)
|
||||||
}
|
}
|
||||||
return fmt.Errorf("no command selected")
|
return fmt.Errorf("no command selected")
|
||||||
}
|
}
|
||||||
|
if c.Kong.usageOnMissing && isMissingChildError(c.Error) {
|
||||||
|
return c.PrintUsage(false)
|
||||||
|
}
|
||||||
return c.RunNode(node, binds...)
|
return c.RunNode(node, binds...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -700,13 +700,7 @@ func checkMissingChildren(node *Node) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(missing) > 5 {
|
return newMissingChildError(missing)
|
||||||
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, ", "))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're missing any positionals and they're required, return an error.
|
// If we're missing any positionals and they're required, return an error.
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
package kong
|
package kong
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
// ParseError is the error type returned by Kong.Parse().
|
// ParseError is the error type returned by Kong.Parse().
|
||||||
//
|
//
|
||||||
// It contains the parse Context that triggered the error.
|
// It contains the parse Context that triggered the error.
|
||||||
@@ -10,3 +15,29 @@ type ParseError struct {
|
|||||||
|
|
||||||
// Cause returns the original cause of the error.
|
// Cause returns the original cause of the error.
|
||||||
func (p *ParseError) Cause() error { return p.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
|
||||||
|
}
|
||||||
|
|||||||
@@ -219,7 +219,10 @@ func (k *Kong) Parse(args []string) (ctx *Context, err error) {
|
|||||||
return nil, &ParseError{error: err, Context: ctx}
|
return nil, &ParseError{error: err, Context: ctx}
|
||||||
}
|
}
|
||||||
if err = ctx.Validate(); err != nil {
|
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 {
|
if err = k.applyHook(ctx, "AfterApply"); err != nil {
|
||||||
return nil, &ParseError{error: err, Context: ctx}
|
return nil, &ParseError{error: err, Context: ctx}
|
||||||
|
|||||||
Reference in New Issue
Block a user