Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cli: improve output and consistency for unknown (sub)commands #5234

Merged
merged 2 commits into from
Jul 16, 2024

Conversation

thaJeztah
Copy link
Member

@thaJeztah thaJeztah commented Jul 4, 2024

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

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

- Description for the changelog

- improve output and consistency for unknown (sub)commands
- improve output for invalid arguments

- A picture of a cute animal (not mandatory but encouraged)

@codecov-commenter
Copy link

codecov-commenter commented Jul 4, 2024

Codecov Report

Attention: Patch coverage is 61.90476% with 8 lines in your changes missing coverage. Please review.

Project coverage is 61.46%. Comparing base (5aae44b) to head (c60b360).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #5234      +/-   ##
==========================================
- Coverage   61.48%   61.46%   -0.03%     
==========================================
  Files         298      298              
  Lines       20813    20816       +3     
==========================================
- Hits        12797    12794       -3     
- Misses       7104     7110       +6     
  Partials      912      912              

@thaJeztah thaJeztah marked this pull request as draft July 4, 2024 23:28
@thaJeztah thaJeztah changed the title cli: improve output and consistency for missing (sub)commands cli: improve output and consistency for unknown (sub)commands Jul 5, 2024
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 <[email protected]>
@thaJeztah thaJeztah force-pushed the nicer_missing_commands branch 3 times, most recently from 5590f9a to 3efd491 Compare July 5, 2024 01:04
@thaJeztah thaJeztah self-assigned this Jul 5, 2024
@thaJeztah thaJeztah force-pushed the nicer_missing_commands branch 7 times, most recently from 642bde5 to 0a836a9 Compare July 5, 2024 01:32
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 <[email protected]>
@thaJeztah thaJeztah force-pushed the nicer_missing_commands branch from 0a836a9 to c60b360 Compare July 5, 2024 01:35
@thaJeztah thaJeztah marked this pull request as ready for review July 5, 2024 09:49
@thaJeztah thaJeztah requested review from silvin-lubecki and a team as code owners July 5, 2024 09:49
Copy link
Contributor

@krissetto krissetto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall LGTM, just left a small suggestion in the comments

@@ -14,15 +12,20 @@ func NoArgs(cmd *cobra.Command, args []string) error {
}

if cmd.HasSubCommands() {
return errors.Errorf("\n" + strings.TrimRight(cmd.UsageString(), "\n"))
return errors.Errorf(
"%[1]s: unknown command: %[2]s %[3]s\n\nUsage: %[4]s\n\nRun '%[2]s --help' for more information",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency with other error messages where we print out commands the user has inputted (or could input, like Run '%[2]s --help' for more information further in this message), maybe it could make sense to surround %[2]s %[3]s with single quotes' as well.

I think it could make the message a little bit more readable, given we are prefixing docker: as well. WDYT?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OHMAN I went back and forth on some of these; initially I had the quotes, but then also looked at unknown flag: which didn't have them; that one is generated by Cobra (or spf13/flags), so not something I could immediately change.

Overall I somewhat think that the quotes may be good to add yes; perhaps still ok for a follow-up pass?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah for sure! It's definitely a minor thing, but if users are anything like me they do appreciate consistency in the outputs. We'll get to it in a separate pass 👍

Copy link
Member

@Benehiko Benehiko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@thaJeztah thaJeztah merged commit ce4469a into docker:master Jul 16, 2024
88 checks passed
@thaJeztah thaJeztah deleted the nicer_missing_commands branch July 16, 2024 23:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants