@@ -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>
|
||||
## Branching positional arguments
|
||||
|
||||
@@ -419,6 +421,7 @@ Tag | Description
|
||||
`type:"X"` | Specify [named types](#custom-named-types) to use.
|
||||
`placeholder:"X"` | Placeholder text.
|
||||
`default:"X"` | Default value.
|
||||
`default:"1"` | On a command, make it the default.
|
||||
`short:"X"` | Short name, if flag.
|
||||
`required` | If present, flag/arg is required.
|
||||
`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)
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
@@ -617,6 +635,7 @@ func checkMissingChildren(node *Node) error {
|
||||
missing = append(missing, strconv.Quote(strings.Join(missingArgs, " ")))
|
||||
}
|
||||
|
||||
haveDefault := 0
|
||||
for _, child := range node.Children {
|
||||
if child.Hidden {
|
||||
continue
|
||||
@@ -627,10 +646,19 @@ func checkMissingChildren(node *Node) error {
|
||||
}
|
||||
missing = append(missing, strconv.Quote(child.Summary()))
|
||||
} 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))
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -815,3 +815,38 @@ func TestIssue40EnumAcrossCommands(t *testing.T) {
|
||||
_, err = p.Parse([]string{"three", "c"})
|
||||
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