Allow parent flags to be processed #4

This commit is contained in:
Gerald Kaszuba
2018-05-19 13:58:35 +10:00
committed by Alec Thomas
parent 3b21a54094
commit a9179cd8ec
3 changed files with 26 additions and 8 deletions
+8 -6
View File
@@ -65,7 +65,7 @@ func (k *Kong) Parse(args []string) (command string, err error) {
} }
}() }()
k.reset(k.Model) k.reset(k.Model)
cmd, err := k.applyNode(Scan(args...), k.Model) cmd, err := k.applyNode(Scan(args...), k.Model, nil)
return strings.Join(cmd, " "), err return strings.Join(cmd, " "), err
} }
@@ -91,8 +91,10 @@ func (k *Kong) reset(node *Node) {
} }
} }
func (k *Kong) applyNode(scan *Scanner, node *Node) (command []string, err error) { // nolint: gocyclo func (k *Kong) applyNode(scan *Scanner, node *Node, flags []*Flag) (command []string, err error) { // nolint: gocyclo
positional := 0 positional := 0
flags = append(flags, node.Flags...) // Track all parent flags.
for token := scan.Pop(); token.Type != EOLToken; token = scan.Pop() { for token := scan.Pop(); token.Type != EOLToken; token = scan.Pop() {
switch token.Type { switch token.Type {
case UntypedToken: case UntypedToken:
@@ -136,14 +138,14 @@ func (k *Kong) applyNode(scan *Scanner, node *Node) (command []string, err error
scan.PushTyped(token.Value[0:1], ShortFlagToken) scan.PushTyped(token.Value[0:1], ShortFlagToken)
case FlagToken: case FlagToken:
if err := matchFlags(node.Flags, token, scan, func(f *Flag) bool { if err := matchFlags(flags, token, scan, func(f *Flag) bool {
return f.Name == token.Value return f.Name == token.Value
}); err != nil { }); err != nil {
return nil, err return nil, err
} }
case ShortFlagToken: case ShortFlagToken:
if err := matchFlags(node.Flags, token, scan, func(f *Flag) bool { if err := matchFlags(flags, token, scan, func(f *Flag) bool {
return string(f.Name) == token.Value return string(f.Name) == token.Value
}); err != nil { }); err != nil {
return nil, err return nil, err
@@ -173,7 +175,7 @@ func (k *Kong) applyNode(scan *Scanner, node *Node) (command []string, err error
if branch.Command.Name == token.Value { if branch.Command.Name == token.Value {
scan.Pop() scan.Pop()
command = append(command, branch.Command.Name) command = append(command, branch.Command.Name)
cmd, err := k.applyNode(scan, branch.Command) cmd, err := k.applyNode(scan, branch.Command, flags)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -184,7 +186,7 @@ func (k *Kong) applyNode(scan *Scanner, node *Node) (command []string, err error
arg := branch.Argument.Argument arg := branch.Argument.Argument
if err := arg.Decode(scan); err == nil { if err := arg.Decode(scan); err == nil {
command = append(command, "<"+arg.Name+">") command = append(command, "<"+arg.Name+">")
cmd, err := k.applyNode(scan, &branch.Argument.Node) cmd, err := k.applyNode(scan, &branch.Argument.Node, flags)
if err != nil { if err != nil {
return nil, err return nil, err
} }
+16
View File
@@ -134,3 +134,19 @@ func TestCantMixPositionalAndBranches(t *testing.T) {
_, err := New(&cli) _, err := New(&cli)
require.Error(t, err) require.Error(t, err)
} }
func TestPropagatedFlags(t *testing.T) {
var cli struct {
Flag1 string
Command1 struct {
Flag2 bool
Command2 struct{} `cmd:""`
} `cmd:""`
}
parser := mustNew(t, &cli)
_, err := parser.Parse([]string{"command-1", "command-2", "--flag-2", "--flag-1=moo"})
require.NoError(t, err)
require.Equal(t, "moo", cli.Flag1)
require.Equal(t, true, cli.Command1.Flag2)
}
+1 -1
View File
@@ -20,7 +20,7 @@ type Node struct {
Children []*Branch Children []*Branch
} }
// A Value is either a flag or a variaable positional argument. // A Value is either a flag or a variable positional argument.
type Value struct { type Value struct {
Flag bool // True if flag, false if positional argument. Flag bool // True if flag, false if positional argument.
Name string Name string