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>
This makes a quick pass through our tests;
Discard output/err
----------------------------------------------
Many tests were testing for error-conditions, but didn't discard output.
This produced a lot of noise when running the tests, and made it hard
to discover if there were actual failures, or if the output was expected.
For example:
=== RUN TestConfigCreateErrors
Error: "create" requires exactly 2 arguments.
See 'create --help'.
Usage: create [OPTIONS] CONFIG file|- [flags]
Create a config from a file or STDIN
Error: "create" requires exactly 2 arguments.
See 'create --help'.
Usage: create [OPTIONS] CONFIG file|- [flags]
Create a config from a file or STDIN
Error: error creating config
--- PASS: TestConfigCreateErrors (0.00s)
And after discarding output:
=== RUN TestConfigCreateErrors
--- PASS: TestConfigCreateErrors (0.00s)
Use sub-tests where possible
----------------------------------------------
Some tests were already set-up to use test-tables, and even had a usable
name (or in some cases "error" to check for). Change them to actual sub-
tests. Same test as above, but now with sub-tests and output discarded:
=== RUN TestConfigCreateErrors
=== RUN TestConfigCreateErrors/requires_exactly_2_arguments
=== RUN TestConfigCreateErrors/requires_exactly_2_arguments#01
=== RUN TestConfigCreateErrors/error_creating_config
--- PASS: TestConfigCreateErrors (0.00s)
--- PASS: TestConfigCreateErrors/requires_exactly_2_arguments (0.00s)
--- PASS: TestConfigCreateErrors/requires_exactly_2_arguments#01 (0.00s)
--- PASS: TestConfigCreateErrors/error_creating_config (0.00s)
PASS
It's not perfect in all cases (in the above, there's duplicate "expected"
errors, but Go conveniently adds "#01" for the duplicate). There's probably
also various tests I missed that could still use the same changes applied;
we can improve these in follow-ups.
Set cmd.Args to prevent test-failures
----------------------------------------------
When running tests from my IDE, it compiles the tests before running,
then executes the compiled binary to run the tests. Cobra doesn't like
that, because in that situation `os.Args` is taken as argument for the
command that's executed. The command that's tested now sees the test-
flags as arguments (`-test.v -test.run ..`), which causes various tests
to fail ("Command XYZ does not accept arguments").
# compile the tests:
go test -c -o foo.test
# execute the test:
./foo.test -test.v -test.run TestFoo
=== RUN TestFoo
Error: "foo" accepts no arguments.
The Cobra maintainers ran into the same situation, and for their own
use have added a special case to ignore `os.Args` in these cases;
https://github.com/spf13/cobra/blob/v1.8.1/command.go#L1078-L1083
args := c.args
// Workaround FAIL with "go test -v" or "cobra.test -test.v", see #155
if c.args == nil && filepath.Base(os.Args[0]) != "cobra.test" {
args = os.Args[1:]
}
Unfortunately, that exception is too specific (only checks for `cobra.test`),
so doesn't automatically fix the issue for other test-binaries. They did
provide a `cmd.SetArgs()` utility for this purpose
https://github.com/spf13/cobra/blob/v1.8.1/command.go#L276-L280
// SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden
// particularly useful when testing.
func (c *Command) SetArgs(a []string) {
c.args = a
}
And the fix is to explicitly set the command's args to an empty slice to
prevent Cobra from falling back to using `os.Args[1:]` as arguments.
cmd := newSomeThingCommand()
cmd.SetArgs([]string{})
Some tests already take this issue into account, and I updated some tests
for this, but there's likely many other ones that can use the same treatment.
Perhaps the Cobra maintainers would accept a contribution to make their
condition less specific and to look for binaries ending with a `.test`
suffix (which is what compiled binaries usually are named as).
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Use the `XXXVar` equivalent for flags that don't have a shorthand flag
instead of passing an empty string for the shorthand flag.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- Prevent completion on "create" subcommands to prevent them
from completing with local filenames
- Add completion for "docker image save"
- Add completion for "docker image tag"
- Disable completion for "docker login"
- Exclude "paused" containers for "docker container attach" and
"docker container exec"
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- make it possible to extract the formatter implementation from the
"common" code, that way, the formatter package stays small
- extract some formatter into their own packages
This is essentially moving the "formatter" implementation of each type
in their respective packages. The *main* reason to do that, is to be
able to depend on `cli/command/formatter` without depending of the
implementation detail of the formatter. As of now, depending on
`cli/command/formatter` means we depend on `docker/docker/api/types`,
`docker/licensing`, … — that should not be the case. `formatter`
should hold the common code (or helpers) to easily create formatter,
not all formatter implementations.
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
This patch adds annotations to mark the checkpoint commands as Linux only, which
hides them if the daemon is running a non-matching operating-system type;
Before:
docker
Usage: docker COMMAND
A self-sufficient runtime for containers
...
Management Commands:
config Manage Docker configs
container Manage containers
image Manage images
After:
docker
Usage: docker COMMAND
A self-sufficient runtime for containers
...
Management Commands:
checkpoint Manage checkpoints
config Manage Docker configs
container Manage containers
image Manage images
This change also prints errors when attempting to use checkpoint commands or
flags if the feature is not supported by the Daemon's operating system;
$ docker checkpoint --help
docker checkpoint is only supported on a Docker daemon running on linux, but the Docker daemon is running on windows
$ docker checkpoint create --help
docker checkpoint create is only supported on a Docker daemon running on linux, but the Docker daemon is running on windows
$ docker checkpoint ls --help
docker checkpoint ls is only supported on a Docker daemon running on linux, but the Docker daemon is running on windows
$ docker checkpoint rm --help
docker checkpoint rm is only supported on a Docker daemon running on linux, but the Docker daemon is running on windows
$ docker container start --checkpoint=foo mycontainer
"--checkpoint" requires the Docker daemon to run on linux, but the Docker daemon is running on windows
$ docker container start --checkpoint-dir=/foo/bar mycontainer
"--checkpoint-dir" requires the Docker daemon to run on linux, but the Docker daemon is running on windows
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Since go 1.7, "context" is a standard package. Since go 1.9,
x/net/context merely provides some types aliased to those in
the standard context package.
The changes were performed by the following script:
for f in $(git ls-files \*.go | grep -v ^vendor/); do
sed -i 's|golang.org/x/net/context|context|' $f
goimports -w $f
for i in 1 2; do
awk '/^$/ {e=1; next;}
/\t"context"$/ {e=0;}
{if (e) {print ""; e=0}; print;}' < $f > $f.new && \
mv $f.new $f
goimports -w $f
done
done
[v2: do awk/goimports fixup twice]
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
The validation functions to test for the number of passed arguments did not
pluralize `argument(s)`, and used `argument(s)` in all cases.
This patch adds a simple `pluralize()` helper to improve this.
Before this change, `argument(s)` was used in all cases:
$ docker container ls foobar
"docker container ls" accepts no argument(s).
$ docker network create one two
"docker network create" requires exactly 1 argument(s).
$ docker network connect
"docker network connect" requires exactly 2 argument(s).
$ docker volume create one two
"docker volume create" requires at most 1 argument(s).
After this change, `argument(s)` is properly singularized or plurarized:
$ docker container ls foobar
"docker container ls" accepts no arguments.
$ docker network create one two
"docker network create" requires exactly 1 argument.
$ docker network connect
"docker network connect" requires exactly 2 arguments.
$ docker volume create one two
"docker volume create" requires at most 1 argument.
Test cases were updated accordingly.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>