Fix Parsing of Nested Subcommands (#9236)

This commit is contained in:
Nishant Das 2021-07-21 19:01:33 +08:00 committed by GitHub
parent 11d9e7da9b
commit 2ffe8336fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 69 additions and 1 deletions

View File

@ -257,13 +257,28 @@ func LoadFlagsFromConfig(cliCtx *cli.Context, flags []cli.Flag) error {
// ValidateNoArgs insures that the application is not run with erroneous arguments or flags.
// This function should be used in the app.Before, whenever the application supports a default command.
func ValidateNoArgs(ctx *cli.Context) error {
commandList := ctx.App.Commands
for _, a := range ctx.Args().Slice() {
if strings.HasPrefix(a, "-") {
continue
}
if c := ctx.App.Command(a); c == nil {
c := checkCommandList(commandList, a)
if c == nil {
return fmt.Errorf("unrecognized argument: %s", a)
}
// Set the command list as the subcommand's
// from the current selected parent command.
commandList = c.Subcommands
}
return nil
}
// verifies that the provided command is in the command list.
func checkCommandList(commands []*cli.Command, name string) *cli.Command {
for _, c := range commands {
if c.Name == name {
return c
}
}
return nil
}

View File

@ -55,6 +55,24 @@ func TestValidateNoArgs(t *testing.T) {
Commands: []*cli.Command{
{
Name: "bar",
Subcommands: []*cli.Command{
{
Name: "subComm1",
Subcommands: []*cli.Command{
{
Name: "subComm3",
},
},
},
{
Name: "subComm2",
Subcommands: []*cli.Command{
{
Name: "subComm4",
},
},
},
},
},
},
}
@ -71,4 +89,39 @@ func TestValidateNoArgs(t *testing.T) {
// It should fail on unregistered flag (default logic in urfave/cli).
err = app.Run([]string{"command", "bar", "--baz"})
require.ErrorContains(t, "flag provided but not defined", err)
// Handle Nested Subcommands
err = app.Run([]string{"command", "bar", "subComm1"})
require.NoError(t, err)
err = app.Run([]string{"command", "bar", "subComm2"})
require.NoError(t, err)
// Should fail from unknown subcommands.
err = app.Run([]string{"command", "bar", "subComm3"})
require.ErrorContains(t, "unrecognized argument: subComm3", err)
err = app.Run([]string{"command", "bar", "subComm4"})
require.ErrorContains(t, "unrecognized argument: subComm4", err)
// Should fail with invalid double nested subcommands.
err = app.Run([]string{"command", "bar", "subComm1", "subComm2"})
require.ErrorContains(t, "unrecognized argument: subComm2", err)
err = app.Run([]string{"command", "bar", "subComm1", "subComm4"})
require.ErrorContains(t, "unrecognized argument: subComm4", err)
err = app.Run([]string{"command", "bar", "subComm2", "subComm1"})
require.ErrorContains(t, "unrecognized argument: subComm1", err)
err = app.Run([]string{"command", "bar", "subComm2", "subComm3"})
require.ErrorContains(t, "unrecognized argument: subComm3", err)
// Should pass with correct nested double subcommands.
err = app.Run([]string{"command", "bar", "subComm1", "subComm3"})
require.NoError(t, err)
err = app.Run([]string{"command", "bar", "subComm2", "subComm4"})
require.NoError(t, err)
}