Skip to content

Commit

Permalink
Ignore unknown arguments on the top-level command.
Browse files Browse the repository at this point in the history
This allows passing argument to plugins, otherwise they are caught by the parse
loop, since cobra does not know about each plugin at this stage (to avoid
having to always scan for all plugins) this means that e.g. `docker plugin
--foo` would accumulate `plugin` as an arg to the `docker` command, then choke
on the unknown `--foo`.

This allows unknown global args only, unknown arguments on subcommands (e.g.
`docker ps --foo`) are still correctly caught.

Add an e2e test covering this case.

Signed-off-by: Ian Campbell <ijc@docker.com>
  • Loading branch information
Ian Campbell committed Jan 29, 2019
1 parent f133f52 commit 197811b
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 2 deletions.
5 changes: 4 additions & 1 deletion cli-plugins/examples/helloworld/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func main() {
},
}

var who string
cmd := &cobra.Command{
Use: "helloworld",
Short: "A basic Hello World plugin for tests",
Expand All @@ -41,9 +42,11 @@ func main() {
// hook.
PersistentPreRunE: plugin.PersistentPreRunE,
Run: func(cmd *cobra.Command, args []string) {
fmt.Fprintln(dockerCli.Out(), "Hello World!")
fmt.Fprintf(dockerCli.Out(), "Hello %s!\n", who)
},
}
flags := cmd.Flags()
flags.StringVar(&who, "who", "World", "Who are we addressing?")

cmd.AddCommand(goodbye, apiversion)
return cmd
Expand Down
10 changes: 10 additions & 0 deletions cmd/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ func newDockerCommand(dockerCli *command.DockerCli) *cobra.Command {
SilenceUsage: true,
SilenceErrors: true,
TraverseChildren: true,
FParseErrWhitelist: cobra.FParseErrWhitelist{
// UnknownFlags ignores any unknown
// --arguments on the top-level docker command
// only. This is necessary to allow passing
// --arguments to plugins otherwise
// e.g. `docker plugin --foo` is caught here
// in the monolithic CLI and `foo` is reported
// as an unknown argument.
UnknownFlags: true,
},
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return command.ShowHelp(dockerCli.Err())(cmd, args)
Expand Down
12 changes: 12 additions & 0 deletions e2e/cli-plugins/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,18 @@ func TestRunGoodSubcommand(t *testing.T) {
})
}

// TestRunGoodArgument ensures correct behaviour when running a valid plugin with an `--argument`.
func TestRunGoodArgument(t *testing.T) {
run, cleanup := prepare(t)
defer cleanup()

res := icmd.RunCmd(run("helloworld", "--who", "Cleveland"))
res.Assert(t, icmd.Expected{
ExitCode: 0,
Out: "Hello Cleveland!",
})
}

// TestHelpGoodSubcommand ensures correct behaviour when invoking help on a
// valid plugin subcommand. A global argument is included to ensure it does not
// interfere.
Expand Down
5 changes: 4 additions & 1 deletion e2e/cli-plugins/testdata/docker-help-helloworld.golden
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@

Usage: docker helloworld COMMAND
Usage: docker helloworld [OPTIONS] COMMAND

A basic Hello World plugin for tests

Options:
--who string Who are we addressing? (default "World")

Commands:
apiversion Print the API version of the server
goodbye Say Goodbye instead of Hello
Expand Down

0 comments on commit 197811b

Please sign in to comment.