Correctly check for required positionals.

This commit is contained in:
Alec Thomas
2018-06-20 22:36:33 +10:00
parent 653531d6bc
commit 4edc701d63
2 changed files with 39 additions and 26 deletions
+4
View File
@@ -1,6 +1,8 @@
package main
import (
"fmt"
"github.com/alecthomas/kong"
)
@@ -24,6 +26,8 @@ func main() {
cmd := kong.Parse(&cli, kong.Description("A shell-like example app."), kong.HelpOptions(kong.CompactHelp()))
switch cmd {
case "rm":
fmt.Println(cli.Rm.Paths, cli.Rm.Force)
case "ls":
}
}
+35 -26
View File
@@ -25,6 +25,21 @@ type Path struct {
Resolved bool
}
// Node returns the Node associated with this Path, or nil if Path is a non-Node.
func (p *Path) Node() *Node {
switch {
case p.App != nil:
return &p.App.Node
case p.Argument != nil:
return p.Argument
case p.Command != nil:
return p.Command
}
return nil
}
// Context contains the current parse context.
type Context struct {
App *Kong
@@ -90,36 +105,30 @@ func (c *Context) Validate() error {
}
}
// Check the terminal node.
path := c.Path[len(c.Path)-1]
switch {
case path.App != nil:
if err := checkMissingChildren(&path.App.Node); err != nil {
return err
}
if err := checkMissingPositionals(0, path.App.Positional); err != nil {
return err
}
node := c.Selected()
if node == nil {
node = &c.App.Model.Node
}
case path.Command != nil:
if err := checkMissingChildren(path.Command); err != nil {
return err
}
if err := checkMissingPositionals(0, path.Parent.Positional); err != nil {
return err
// Find deepest positional argument so we can check if all required positionals have been provided.
positionals := 0
for _, path := range c.Path {
if path.Positional != nil {
positionals = path.Positional.Position + 1
}
}
case path.Argument != nil:
value := path.Argument.Argument
if err := checkMissingChildren(node); err != nil {
return err
}
if err := checkMissingPositionals(positionals, node.Positional); err != nil {
return err
}
if node.Type == ArgumentNode {
value := node.Argument
if value.Required && !value.Set {
return fmt.Errorf("%s is required", path.Argument.Summary())
}
if err := checkMissingChildren(path.Argument); err != nil {
return err
}
case path.Positional != nil:
if err := checkMissingPositionals(path.Positional.Position+1, path.Parent.Positional); err != nil {
return err
return fmt.Errorf("%s is required", node.Summary())
}
}
return nil