Commit Graph

70 Commits

Author SHA1 Message Date
4f7c07cfc2 update local code for updated modules
Some tests had to be skipped as there's some issues to address, and
some of the result-types cannot be mocked / stubbed.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-24 10:28:54 +02:00
f14eeeb361 cli/flags: add "hostVar" to handle --host / -H as a single string
hostVar is used for the '--host' / '-H' flag to set [ClientOptions.Hosts].
The [ClientOptions.Hosts] field is a slice because it was originally shared
with the daemon config. However, the CLI only allows for a single host to
be specified.

hostVar presents itself as a "string", but stores the value in a string
slice. It produces an error when trying to set multiple values, matching
the check in [getServerHost].

[getServerHost]: 7eab668982/cli/command/cli.go (L542-L551)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-18 11:01:39 +02:00
e069ded4c3 cli: reduce uses of pkg/errors for stdlib errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-11 19:00:02 +02:00
062ad57ce2 golangci-lint: enable mirror linter
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-05-19 20:07:05 +02:00
56c2fa6c0e e2e/cli-plugins: use regexp.Compile to prevent panic in tests
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-04-10 12:22:26 +02:00
4321293972 move cli-plugins metadata types/consts to a separate package
This prevents cli-plugins having to import the plugin-manager.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-03-07 12:38:06 +01:00
0cff340983 cmd/docker: do not print error status on exec/run
Co-authored-by: Fabio Pugliese Ornellas <fabio.ornellas@gmail.com>
Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2025-02-21 12:55:57 +01:00
61a3b4bd50 Remove preceding white space from cobra help template
Signed-off-by: thelovekesh <lovekesh.kumar@rtcamp.com>
Signed-off-by: Lovekesh Kumar <lovekesh.kumar@rtcamp.com>
2025-02-10 10:51:25 +01:00
b10b79e6fd cli-plugins: minor cleanups: use Println
- use Println to print newline instead of custom format
- suppress some errors to make my IDE and linters happier
- use res.Assert() with icmd.Expected{} where possible to make
  assertions not depend on newline / whitespace randomness
- use apiClient instead of client for the API client to
  prevent shadowing imports.
- use dockerCLI with Go's standard camelCase casing.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-02-03 12:18:07 +01:00
6489a777e5 e2e: remove redundant capturing of loop vars in tests (copyloopvar)
go1.22 and up now produce a unique variable in loops, tehrefore no longer
requiring to capture the variable manually;

    service/logs/parse_logs_test.go:50:3: The copy of the 'for' variable "tc" can be deleted (Go 1.22+) (copyloopvar)
            tc := tc
            ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-05 10:14:30 +01:00
f28fc7f82f cli: FlagErrorFunc: don't print long usage output for invalid flags
When trying to use an invalid flag, the CLI currently prints the a short
error message, instructions to use the `--help` flag to learn about the
correct usage, followed by the command's usage output.

While this is a common convention, and may have been a nice gesture when
docker was still young and only had a few commands and options ("you did
something wrong, but here's an overview of what you can use"), that's no
longer the case, and many commands have a _very_ long output.

The result of this is that the error message, which is the relevant
information in this case - "You mis-typed something" - is lost in the
output, and hard to find (sometimes even requiring scrolling back).

The output is also confusing, because it _looks_ like something ran
successfully (most of the output is not about the error!).

Even further; the suggested resolution (try `--help` to see the correct
options) is rather redundant, because running teh command with `--help`
produces _exactly_ the same output as was just showh, baring the error
message. As a fun fact, due to the usage output being printed, the
output even contains not one, but _two_ "call to actions";

- `See 'docker volume --help'.` (under the erro message)
- `Run 'docker volume COMMAND --help' for more information on a command.`
  (under the usage output)

In short; the output is too verbose, confusing, and doesn't provide
a good UX. Let's reduce the output produced so that the focus is on the
important information.

This patch:

- Changes the usage to the short-usage.
- Prefixes the error message with the binary / root-command name
  (usually `docker:`) to be consistent with `unknon command`, and helps
  to distinguish where the message originated from (the `docker` CLI in
  this case).
- Adds an empty line between the error-message and the "call to action"
  (`Run 'docker volume --help' ...` in the example below). This helps
  separating the error message ("unkown flag") from the call-to-action.

Before this patch:

    docker volume --no-such-flag
    unknown flag: --no-such-flag
    See 'docker volume --help'.

    Usage:  docker volume COMMAND

    Manage volumes

    Commands:
      create      Create a volume
      inspect     Display detailed information on one or more volumes
      ls          List volumes
      prune       Remove unused local volumes
      rm          Remove one or more volumes
      update      Update a volume (cluster volumes only)

    Run 'docker volume COMMAND --help' for more information on a command.

With this patch:

    docker volume --no-such-flag
    docker: unknown flag: --no-such-flag

    Usage:  docker volume COMMAND

    Run 'docker volume --help' for more information

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-07-17 13:22:31 +02:00
ce4469a696 Merge pull request #5234 from thaJeztah/nicer_missing_commands
cli: improve output and consistency for unknown (sub)commands
2024-07-17 01:22:03 +02:00
3dd6fc365d cmd/docker: don't discard cli.StatusError errors without custom message
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-07-05 10:59:27 +02:00
2f83064ec4 e2e/cli-plugins: check for exit-errors in tests
Verify that we get the expected exit-code, not just the message.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-07-05 10:59:26 +02:00
baf35da401 e2e/cli-plugins: use cmd.CombinedOutput() instead of custom buffer
Also remove a debug-log, as the output would already be shown if
the test would fail.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-07-05 10:59:26 +02:00
c6b40640cc e2e/cli-plugins: use identifiable output for test
This confused me fore a bit, because I thought the test was checking for
an actual `context.Canceled` error (which is spelled "context canceled"
with a single "l". But then I found that this was a string that's printed
as part of a test-utility, just looking very similar but with the British
spelling ("cancelled").

Let's change this to a message that's unique for the test, also to make it
more grep'able.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-07-05 10:59:26 +02:00
e9f32edac5 e2e/cli-plugins: explicitly ignore fmt.Printxx errors
To keep some linters happier, and my IDE to be less noisy.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-07-05 10:59:26 +02:00
5e7948ec83 e2e/cli-plugins: rename var that shadowed import
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-07-05 10:59:13 +02:00
c60b360c33 cli: improve argument validation output
Improve the output for these validation errors:

- Removes the short command description from the output. This information
  does not provide much useful help, and distracts from the error message.
- Reduces punctuation, and
- Prefixes the error message with the binary / root-command name
  (usually `docker:`) to be consistent with other similar errors.
- Adds an empty line between the error-message and the "call to action"
  (`Run 'docker volume --help'...` in the example below). This helps
  separating the error message and "usage" from the call-to-action.

Before this patch:

    $ docker volume ls one two three
    "docker volume ls" accepts no arguments.
    See 'docker volume ls --help'.

    Usage:  docker volume ls [OPTIONS]

    List volumes

    $ docker volume create one two three
    "docker volume create" requires at most 1 argument.
    See 'docker volume create --help'.

    Usage:  docker volume create [OPTIONS] [VOLUME]

    Create a volume

With this patch:

    $ docker volume ls one two three
    docker: 'docker volume ls' accepts no arguments

    Usage:  docker volume ls [OPTIONS]

    Run 'docker volume ls --help' for more information

    $ docker voludocker volume create one two three
    docker: 'docker volume create' requires at most 1 argument

    Usage:  docker volume create [OPTIONS] [VOLUME]

    SRun 'docker volume create --help' for more information

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-07-05 03:35:14 +02:00
a6e96c758e cli: improve output and consistency for unknown (sub)commands
Before this patch, output for invalid top-level and sub-commands differed.
For top-level commands, the CLI would print an error-message and a suggestion
to use `--help`. For missing *subcommands*, we would hit a different code-path,
and different output, which includes full "usage" / "help" output.

While it is a common convention to show usage output, and may have been
a nice gesture when docker was still young and only had a few commands
and options ("you did something wrong; here's an overview of what you
can use"), that's no longer the case, and many commands have a _very_
long output.

The result of this is that the error message, which is the relevant
information in this case - "You mis-typed something" - is lost in the
output, and hard to find (sometimes even requiring scrolling back).

The output is also confusing, because it _looks_ like something ran
successfully (most of the output is not about the error!).

Even further; the suggested resolution (try `--help` to see the correct
options) is rather redundant, because running teh command with `--help`
produces _exactly_ the same output as was just showh, baring the error
message. As a fun fact, due to the usage output being printed, the
output even contains not one, but _two_ "call to actions";

- `See 'docker volume --help'.` (under the erro message)
- `Run 'docker volume COMMAND --help' for more information on a command.`
  (under the usage output)

In short; the output is too verbose, confusing, and doesn't provide
a good UX. Let's reduce the output produced so that the focus is on the
important information.

This patch:

- Changes the usage to the short-usage.
- Changes the error-message to mention the _full_ command instead of only
  the command after `docker` (so `docker no-such-command` instead of
  `no-such-command`).
- Prefixes the error message with the binary / root-command name
  (usually `docker:`); this is something we can still decide on, but
  it's a pattern we already use in some places. The motivation for this
  is that `docker` commands can often produce output that's a combination
  of output from the CLI itself, output from the daemon, and even output
  from the container. The `docker:` prefix helps to distinguish where
  the message originated from (the `docker` CLI in this case).
- Adds an empty line between the error-message and the "call to action"
  (`Run 'docker volume --help'...` in the example below). This helps
  separating the error message ("unkown flag") from the call-to-action.

Before this patch:

Unknown top-level command:

    docker nosuchcommand foo
    docker: 'nosuchcommand' is not a docker command.
    See 'docker --help'

Unknown sub-command:

    docker volume nosuchcommand foo

    Usage:  docker volume COMMAND

    Manage volumes

    Commands:
      create      Create a volume
      inspect     Display detailed information on one or more volumes
      ls          List volumes
      prune       Remove unused local volumes
      rm          Remove one or more volumes
      update      Update a volume (cluster volumes only)

    Run 'docker volume COMMAND --help' for more information on a command.

After this patch:

Unknown top-level command:

    docker nosuchcommand foo
    docker: unknown command: docker nosuchcommand

    Run 'docker --help' for more information

Unknown sub-command:

    docker volume nosuchcommand foo
    docker: unknown command: 'docker volume nosuchcommand'

    Usage:  docker volume COMMAND

    Run 'docker volume --help' for more information

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-07-05 02:28:11 +02:00
e06ef800fc Removed all mentions of "please" from docs and messages
Signed-off-by: Grace Choi <gracechoi@utexas.edu>
Signed-off-by: Pranjal Rai <pranjalrai@utexas.edu>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-06-11 16:53:40 +02:00
86162f7816 feat: use main func ctx for cobra and use ctx in tests
Explicitly create the context and set it on the CLI, instead of depending on
NewDockerCli() to instance a default context.

Co-authored-by: Sebastiaan van Stijn <github@gone.nl>
Co-authored-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>

Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2024-04-25 12:00:31 +02:00
abe78b79de chore: docker help should not show plugin vendor and version
Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
2024-02-29 08:47:18 +01:00
cfa9fef77d tests: add plugin-socket-compatibility tests
Adds a new plugin to the e2e plugins that simulates an older
plugin binary and a test suite to ensure older plugin binaries
keep behaving the same with newer CLI versions.

Signed-off-by: Laura Brehm <laurabrehm@hey.com>
2024-01-29 13:39:58 +00:00
5400a48aaf Plumb contexts through commands
This is to prepare for otel support.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-12-12 22:30:16 +01:00
8661552e7a golangci-lint: enable thelper linter
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-11-20 16:02:17 +01:00
c39c711a18 load plugin command stubs when required
We are currently loading plugin command stubs for every
invocation which still has a significant performance hit.
With this change we are doing this operation only if cobra
completion arg request is found.

- 20.10.23: `docker --version` takes ~15ms
- 23.0.1: `docker --version` takes ~93ms

With this change `docker --version` takes ~9ms

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-28 06:16:55 +02:00
1da95ff6aa format code with gofumpt
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-09-30 11:59:11 +02:00
cbec75e2f3 Adopt Cobra completion v2 to support completion by CLI plugins
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2022-05-12 12:59:10 +02:00
bc2b48aaf2 e2e: cleanup TestGlobalHelp() to be less brittle
- remove check for "A self-sufficient runtime for containers"; really
  not important to check for.
- don't make the checks positional (just match that we find them, and
  that we don't find them multiple times)
- account for leading whitespace to change instead of hard-coding the
  number of spaces before output.
- change the badopt check; I think it should be sufficient to check
  that the bad option was printed and that "run --help" output is
  printed.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-03-27 10:42:48 +02:00
7f3717bd2a Replace tab with spaces in usage output
All output of the usage / --help output uses spaces, and having a tab
in the output can be somewhat cumbersome (e.g. our YAML docs generator
doesn't like them, and copy/pasing the output in iTerm produces a warning).

This patch changes the output to use two spaces instead.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-10-02 15:41:17 +02:00
2c0e93063b bump gotest.tools v3.0.1 for compatibility with Go 1.14
full diff: https://github.com/gotestyourself/gotest.tools/compare/v2.3.0...v3.0.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-02-23 00:28:55 +01:00
6e5528b650 e2e: fix formatting of comments
Comments should have a leading space unless the comment is
for special purposes (go:generate, nolint:)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-01-16 12:46:07 +01:00
1736662bea e2e/cli-plugins: Using the variable on range scope args in function literal (scopelint)
```
e2e/cli-plugins/flags_test.go:135:27: Using the variable on range scope `args` in function literal (scopelint)
			res := icmd.RunCmd(run(args...))
			                       ^
```

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2019-10-31 19:22:34 +01:00
11d2e404c6 Merge pull request #1853 from ijc/cli-plugin-persistentprerun-hook
cli-plugins: fix when plugin does not use PersistentPreRun* hooks
2019-05-13 07:06:42 -07:00
af200f14ed cli-plugins: fix when plugin does not use PersistentPreRun* hooks
This regressed in 3af168c7df ("Ensure plugins can use `PersistentPreRunE`
again.") but this wasn't noticed because the helloworld test plugin has it's
own `PersistentPreRunE` which has the effect of deferring the resolution of the
global variable. In the case where the hook isn't used the variable is resolved
during `newPluginCommand` which is before the global variable was set.

Initialize the plugin command with a stub function wrapping the call to the
(global) hook, this defers resolving the variable until after it has been set,
otherwise the initial value (`nil`) is used in the struct.

Signed-off-by: Ian Campbell <ijc@docker.com>
2019-04-30 10:45:29 +01:00
40a6cf7c47 Include CLI plugins in help output on unknown flag.
Previously `docker --badopt` output would not include CLI plugins.

Fixes #1813

Signed-off-by: Ian Campbell <ijc@docker.com>
2019-04-26 15:21:20 +01:00
d57175aa2e Move subtests of TestGlobalHelp into actual subtests
Signed-off-by: Ian Campbell <ijc@docker.com>
2019-04-26 10:43:03 +01:00
d32f3647b1 e2e: Add tests for #1801 (global args parsed multiple times)
These currently fail.

Signed-off-by: Ian Campbell <ijc@docker.com>
2019-04-03 15:07:38 +01:00
ef40743669 e2e: Add a TestMain for cli plugins tests
This was omitted when these tests were added.

Adding this means that the tests now see the `$DOCKER_HOST` configured (via
`$TEST_DOCKER_HOST`) where they didn't before. In some cases (specifically the
`test-e2e-connhelper-ssh` case) this results in additional output on stderr
when `-D` (debug) is used:

    time="2019-04-03T11:10:27Z" level=debug msg="commandconn: starting ssh with [-l penguin 172.20.0.2 -- docker system dial-stdio]"

Address this by switching the affected test cases to use `-l info` instead of
`-D`, they all just require some option not specifically `-D`. Note that `info`
is the default log level so this is effectively a nop (which is good).

Signed-off-by: Ian Campbell <ijc@docker.com>
2019-04-03 15:06:34 +01:00
add2da66c5 e2e: Use icmd.None in a couple more places
This checks for actual emptiness, while `""` means "don't care".

Signed-off-by: Ian Campbell <ijc@docker.com>
2019-04-03 11:07:52 +01:00
8f3798cf04 cli-plugins: Reinstate deprecated -h short form of --help.
In the initial implementation I thought it would be good to not pass on the
deprecation to plugins (since they are new). However it turns out this causes
`docker helloworld -h` to print a spurious "pflag: help requested" line:

    $ docker helloworld -h
    pflag: help requested
    See 'docker helloworld --help'.

    Usage:	docker helloworld [OPTIONS] COMMAND

    A basic Hello World plugin for tests
    ...

Compared with:

    $ docker ps -h
    Flag shorthand -h has been deprecated, please use --help

    Usage:	docker ps [OPTIONS]

This is in essence because having the flag undefined hits a different path
within cobra, causing `c.execute()` to return early due to getting an error
(`flag.ErrHelp`) from `c.ParseFlags`, which launders the error through our
`FlagErrorFunc` which wraps it in a `StatusError` which in turn defeats an `if
err == flag.ErrHelp` check further up the call chain. If the flag is defined we
instead hit a path which returns a bare `flag.ErrHelp` without wrapping it.

I considered updating our `FlagErrorFunc` to not wrap `flag.ErrHelp` (and then
following the chain to the next thing) however while doing that I realised that
the code for `-h` (and `--help`) is deeply embedded into cobra (and its flags
library) such that actually using `-h` as a plugin argument meaning something
other than `help` is basically impossible/impractical. Therefore we may as well
have plugins behave identically to the monolithic CLI and support (deprecated)
the `-h` argument.

With this changed the help related blocks of `SetupRootCommand` and
`SetupPluginRootCommand` are now identical, so consolidate into
`setupCommonRootCommand`.

Tests are updated to check `-h` in a variety of scenarios, including the happy
case here.

Signed-off-by: Ian Campbell <ijc@docker.com>
2019-03-28 17:18:20 +00:00
0b30592ee0 e2e/cli-plugins: improve checks for empty output by using icmd.None
In some cases this means switching to `icmd.Expected` rather than
`icmd.Success`, but this improves readability overall.

Signed-off-by: Ian Campbell <ijc@docker.com>
2019-03-28 14:30:51 +00:00
cfd5b16ae0 Merge pull request #1745 from ijc/disable-dial-stdio-for-plugins
cli-plugins: disable use of dial-stdio
2019-03-18 12:29:41 +01:00
ff2ed6efa8 cli-plugins: disable use of dial-stdio
Since #1654 so far we've had problems with it not working on Windows (npipe
lacked the `CloseRead` method) and problems with using tcp with tls (the tls
connection also lacks `CloseRead`). Both of these were workedaround in #1718
which added a nop `CloseRead` method.

However I am now seeing hangs (on Windows) where the `system dial-stdio`
subprocess is not exiting (I'm unsure why so far).

I think the 3rd problem found with this is an indication that `dial-stdio` is
not quite ready for wider use outside of its initial usecase (support for
`ssh://` URLs to connect to remote daemons).

This change simply disables the `dial-stdio` path for all plugins. However
rather than completely reverting 891b3d953e ("cli-plugins: use `docker system
dial-stdio` to call the daemon") I've just disabled the functionality at the
point of use and left in a trap door environment variable so that those who
want to experiment with this mode (and perhaps fully debug it) have an easier
path do doing so.

The e2e test for this case is disabled unless the trap door envvar is set. I
also renamed the test to clarify that it is about cli plugins.

Signed-off-by: Ian Campbell <ijc@docker.com>
2019-03-18 10:58:51 +00:00
86a5a489f7 Merge pull request #1690 from jcsirot/fix-contextstore-for-plugins
Always initialize context store
2019-03-18 11:27:07 +01:00
0b794e0620 e2e/cli-plugins: explicitly check that PersistentPreRunE works
I regressed this in d4ced2ef77 ("allow plugins to have argument which match a
top-level flag.") by unconditionally overwriting any `PersistentRunE` that the
user may have supplied.

We need to ensure two things:

1. That the user can use `PersistentRunE` (or `PersistentRun`) for their own
   purposes.
2. That our initialisation always runs, even if the user has used
   `PersistentRun*`, since that will shadow the root.

To do this add a `PersistentRunE` to the helloworld plugin which logs (covers 1
above) and then use it when calling the `apiversion` subcommand (which covers 2
since that uses the client)

Signed-off-by: Ian Campbell <ijc@docker.com>
2019-03-14 14:20:19 +00:00
37fcaf7a29 Resolve the docker Endpoint even if the client already exists. In that case the TestDialStdio e2e test had to be modified: the --tls option triggers an error since the endpoint resolution tries to read the ${DOCKER_CERT_PATH}/ca.pem file which does not exist.
Signed-off-by: Jean-Christophe Sirot <jean-christophe.sirot@docker.com>
2019-03-13 14:18:41 +01:00
2c624e8984 Add e2e test for handling of version/-v/--version with plugins
Previous commits fixed the first issue on #1661, this simply adds a test for
it. Note that this is testing the current behaviour, without regard for the
second issue in #1661 which proposes a different behaviour.

Signed-off-by: Ian Campbell <ijc@docker.com>
2019-03-13 11:28:17 +00:00
d4ced2ef77 allow plugins to have argument which match a top-level flag.
The issue with plugin options clashing with globals is that when cobra is
parsing the command line and it comes across an argument which doesn't start
with a `-` it (in the absence of plugins) distinguishes between "argument to
current command" and "new subcommand" based on the list of registered sub
commands.

Plugins breaks that model. When presented with `docker -D plugin -c foo` cobra
parses up to the `plugin`, sees it isn't a registered sub-command of the
top-level docker (because it isn't, it's a plugin) so it accumulates it as an
argument to the top-level `docker` command. Then it sees the `-c`, and thinks
it is the global `-c` (for AKA `--context`) option and tries to treat it as
that, which fails.

In the specific case of the top-level `docker` subcommand we know that it has
no arguments which aren't `--flags` (or `-f` short flags) and so anything which
doesn't start with a `-` must either be a (known) subcommand or an attempt to
execute a plugin.

We could simply scan for and register all installed plugins at start of day, so
that cobra can do the right thing, but we want to avoid that since it would
involve executing each plugin to fetch the metadata, even if the command wasn't
going to end up hitting a plugin.

Instead we can parse the initial set of global arguments separately before
hitting the main cobra `Execute` path, which works here exactly because we know
that the top-level has no non-flag arguments.

One slight wrinkle is that the top-level `PersistentPreRunE` is no longer
called on the plugins path (since it no longer goes via `Execute`), so we
arrange for the initialisation done there (which has to be done after global
flags are parsed to handle e.g. `--config`) to happen explictly after the
global flags are parsed. Rather than make `newDockerCommand` return the
complicated set of results needed to make this happen, instead return a closure
which achieves this.

The new functionality is introduced via a common `TopLevelCommand` abstraction
which lets us adjust the plugin entrypoint to use the same strategy for parsing
the global arguments. This isn't strictly required (in this case the stuff in
cobra's `Execute` works fine) but doing it this way avoids the possibility of
subtle differences in behaviour.

Fixes #1699, and also, as a side-effect, the first item in #1661.

Signed-off-by: Ian Campbell <ijc@docker.com>
2019-03-13 11:28:17 +00:00