Support OnlySubCommands for validation of positional arguments

Currently, suggestions for "unknown command" are not working for
subcommands.

This patch supports new validation of positional arguments as
`OnlySubCommands`. It accepts only subcommands if enabled, and also
`findSuggestions()` will be called.
This commit is contained in:
Kenjiro Nakayama 2018-02-17 22:49:17 +09:00
parent ef82de70bb
commit 4164386743
3 changed files with 52 additions and 0 deletions

View file

@ -392,6 +392,7 @@ The following validators are built in:
- `NoArgs` - the command will report an error if there are any positional args.
- `ArbitraryArgs` - the command will accept any args.
- `OnlyValidArgs` - the command will report an error if there are any positional args that are not in the `ValidArgs` field of `Command`.
- `OnlySubCommands` - the command will report an error if if any args are included except for subcommands.
- `MinimumNArgs(int)` - the command will report an error if there are not at least N positional args.
- `MaximumNArgs(int)` - the command will report an error if there are more than N positional args.
- `ExactArgs(int)` - the command will report an error if there are not exactly N positional args.

11
args.go
View file

@ -43,6 +43,17 @@ func OnlyValidArgs(cmd *Command, args []string) error {
return nil
}
// OnlySubCommands returns an error if any args are included except for subcommands.
func OnlySubCommands(cmd *Command, args []string) error {
if !cmd.HasSubCommands() {
return nil
}
if len(args) > 0 {
return fmt.Errorf("unknown command %q for %q%s", args[0], cmd.CommandPath(), cmd.findSuggestions(args[0]))
}
return nil
}
// ArbitraryArgs never returns an error.
func ArbitraryArgs(cmd *Command, args []string) error {
return nil

View file

@ -69,6 +69,46 @@ func TestOnlyValidArgsWithInvalidArgs(t *testing.T) {
}
}
func TestOnlySubCommandsArgs(t *testing.T) {
rootCmd := &Command{
Use: "root",
Args: OnlySubCommands,
Run: emptyRun,
}
subCmd := &Command{Use: "sub", Run: emptyRun}
rootCmd.AddCommand(subCmd)
output, err := executeCommand(rootCmd, "sub")
if output != "" {
t.Errorf("Unexpected output: %v", output)
}
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
}
func TestOnlySubCommandsArgsWithInvalidArgs(t *testing.T) {
rootCmd := &Command{
Use: "root",
Args: OnlySubCommands,
Run: emptyRun,
}
subCmd := &Command{Use: "sub", Run: emptyRun}
rootCmd.AddCommand(subCmd)
_, err := executeCommand(rootCmd, "notsub")
if err == nil {
t.Fatal("Expected an error")
}
got := err.Error()
expected := `unknown command "notsub" for "root"`
if got != expected {
t.Errorf("Expected: %q, got: %q", expected, got)
}
}
func TestArbitraryArgs(t *testing.T) {
c := &Command{Use: "c", Args: ArbitraryArgs, Run: emptyRun}
output, err := executeCommand(c, "a", "b")