Support default commands.

Fixes #41.
This commit is contained in:
Alec Thomas
2020-01-23 20:56:25 +11:00
parent 5db71ed657
commit b66dcf3279
3 changed files with 67 additions and 1 deletions
+3
View File
@@ -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
View File
@@ -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
}
+35
View File
@@ -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>")
}