Tracing parser (#11)

* Add tracing to the parser.

* Synthesize a --help flag.

* Parsing now occurs in multiple phases.

1. Reset target.
2. Parse command-line into a "trace" (no values are written to target).
3. Apply traced, parsed values to the target fields.

This is another step in facilitating context-sensitive help and
completion.

* Detect duplicate flags.
This commit is contained in:
Alec Thomas
2018-05-22 00:07:43 -04:00
committed by Gerald Kaszuba
parent 3eb5e285ed
commit ab5cf7e6ef
8 changed files with 247 additions and 77 deletions
+6 -24
View File
@@ -5,7 +5,6 @@ import (
"io"
"os"
"path/filepath"
"strings"
"text/template"
)
@@ -65,31 +64,14 @@ func (k *Kong) Parse(args []string) (command string, err error) {
panic(msg)
}
}()
k.reset(k.Model)
ctx := &ParseContext{
Scan: Scan(args...),
ctx, err := Trace(args, k.Model)
if err != nil {
return "", err
}
err = ctx.applyNode(k.Model)
return strings.Join(ctx.Command, " "), err
}
// Recursively reset values to defaults (as specified in the grammar) or the zero value.
func (k *Kong) reset(node *Node) {
for _, flag := range node.Flags {
flag.Value.Reset()
}
for _, pos := range node.Positional {
pos.Reset()
}
for _, branch := range node.Children {
if branch.Argument != nil {
arg := branch.Argument.Argument
arg.Reset()
k.reset(&branch.Argument.Node)
} else {
k.reset(branch.Command)
}
if value := ctx.FlagValue(k.Model.HelpFlag); value.IsValid() && value.Bool() {
return "", nil
}
return ctx.Apply()
}
func (k *Kong) Errorf(format string, args ...interface{}) {