@@ -293,6 +293,8 @@ type CLI struct {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If a sub-command is tagged with `default:"1"` it will be selected if there are no further arguments.
|
||||||
|
|
||||||
<a id="markdown-branching-positional-arguments" name="branching-positional-arguments"></a>
|
<a id="markdown-branching-positional-arguments" name="branching-positional-arguments"></a>
|
||||||
## Branching positional arguments
|
## Branching positional arguments
|
||||||
|
|
||||||
@@ -419,6 +421,7 @@ Tag | Description
|
|||||||
`type:"X"` | Specify [named types](#custom-named-types) to use.
|
`type:"X"` | Specify [named types](#custom-named-types) to use.
|
||||||
`placeholder:"X"` | Placeholder text.
|
`placeholder:"X"` | Placeholder text.
|
||||||
`default:"X"` | Default value.
|
`default:"X"` | Default value.
|
||||||
|
`default:"1"` | On a command, make it the default.
|
||||||
`short:"X"` | Short name, if flag.
|
`short:"X"` | Short name, if flag.
|
||||||
`required` | If present, flag/arg is required.
|
`required` | If present, flag/arg is required.
|
||||||
`optional` | If present, flag/arg is optional.
|
`optional` | If present, flag/arg is optional.
|
||||||
|
|||||||
+29
-1
@@ -397,6 +397,24 @@ func (c *Context) trace(node *Node) (err error) { // nolint: gocyclo
|
|||||||
return fmt.Errorf("unexpected token %s", token)
|
return fmt.Errorf("unexpected token %s", token)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// End of the line, check for a default command.
|
||||||
|
var defaultNode *Path
|
||||||
|
for _, child := range node.Children {
|
||||||
|
if child.Type == CommandNode && child.Tag.Default != "" {
|
||||||
|
if defaultNode != nil {
|
||||||
|
return fmt.Errorf("can't have more than one default command under %s", node.Summary())
|
||||||
|
}
|
||||||
|
defaultNode = &Path{
|
||||||
|
Parent: child,
|
||||||
|
Command: child,
|
||||||
|
Flags: child.Flags,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if defaultNode != nil {
|
||||||
|
c.Path = append(c.Path, defaultNode)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -617,6 +635,7 @@ func checkMissingChildren(node *Node) error {
|
|||||||
missing = append(missing, strconv.Quote(strings.Join(missingArgs, " ")))
|
missing = append(missing, strconv.Quote(strings.Join(missingArgs, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
haveDefault := 0
|
||||||
for _, child := range node.Children {
|
for _, child := range node.Children {
|
||||||
if child.Hidden {
|
if child.Hidden {
|
||||||
continue
|
continue
|
||||||
@@ -627,10 +646,19 @@ func checkMissingChildren(node *Node) error {
|
|||||||
}
|
}
|
||||||
missing = append(missing, strconv.Quote(child.Summary()))
|
missing = append(missing, strconv.Quote(child.Summary()))
|
||||||
} else {
|
} else {
|
||||||
|
if child.Tag.Default != "" {
|
||||||
|
if len(child.Children) > 0 {
|
||||||
|
return fmt.Errorf("default command %s must not have subcommands or arguments", child.Summary())
|
||||||
|
}
|
||||||
|
haveDefault++
|
||||||
|
}
|
||||||
missing = append(missing, strconv.Quote(child.Name))
|
missing = append(missing, strconv.Quote(child.Name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(missing) == 0 {
|
if haveDefault > 1 {
|
||||||
|
return fmt.Errorf("more than one default command found under %s", node.Summary())
|
||||||
|
}
|
||||||
|
if len(missing) == 0 || haveDefault > 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -815,3 +815,38 @@ func TestIssue40EnumAcrossCommands(t *testing.T) {
|
|||||||
_, err = p.Parse([]string{"three", "c"})
|
_, err = p.Parse([]string{"three", "c"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEnumArg(t *testing.T) {
|
||||||
|
var cli struct {
|
||||||
|
Nested struct {
|
||||||
|
One string `arg:"" enum:"a,b,c"`
|
||||||
|
Two string `arg:""`
|
||||||
|
} `cmd:""`
|
||||||
|
}
|
||||||
|
p := mustNew(t, &cli)
|
||||||
|
_, err := p.Parse([]string{"nested", "a", "b"})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "a", cli.Nested.One)
|
||||||
|
require.Equal(t, "b", cli.Nested.Two)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDefaultCommand(t *testing.T) {
|
||||||
|
var cli struct {
|
||||||
|
One struct{} `cmd:"" default:"1"`
|
||||||
|
Two struct{} `cmd:""`
|
||||||
|
}
|
||||||
|
p := mustNew(t, &cli)
|
||||||
|
ctx, err := p.Parse([]string{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "one", ctx.Command())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMultipleDefaultCommands(t *testing.T) {
|
||||||
|
var cli struct {
|
||||||
|
One struct{} `cmd:"" default:"1"`
|
||||||
|
Two struct{} `cmd:"" default:"1"`
|
||||||
|
}
|
||||||
|
p := mustNew(t, &cli)
|
||||||
|
_, err := p.Parse([]string{})
|
||||||
|
require.EqualError(t, err, "can't have more than one default command under <command>")
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user