Aug 1, 2021

[cli][note] design / Command Line Interface Guidelines

Reference:
https://github.com/cli-guidelines/cli-guidelines

Page:
https://clig.dev/


Basics

  • C++: 3rd party lib; e.g. https://github.com/CLIUtils/CLI11
  • Return zero exit code on success, non-zero on failure.
    • Beware of bash exit code 128.
  • Send output to stdout.
  • Send messaging to stderr.


Help

  • Display help text when passed no options, the -h flag, or the --help flag.
  • Display a concise help text by default.
  • Show full help when -h and --help is passed.
  • Provide a support path for feedback and issues.
  • Lead with examples.
  • Display the most common flags and commands at the start of the help text.
  • Use formatting in your help text.
  • *If the user did something wrong and you can guess what they meant, suggest it.
  • If your command is expecting to have something piped to it and stdin is an interactive terminal,
    display help immediately and quit.


Output

  • Human-readable output is paramount.
  • Have machine-readable output where it does not impact usability.
  • If human-readable output breaks machine-readable output, use
    --plain
    to display output in plain, tabular text format for integration with tools like grep or awk.
  • Display output as formatted JSON if --json is passed.
  • Display output on success, but keep it brief.
  • If you change state, tell the user.
  • Make it easy to see the current state of the system.
  • Suggest commands the user should run.
  • Actions crossing the boundary of the program’s internal world should usually be explicit. 
  • By default, don’t output information that’s only understandable by the creators of the software.
  • Don’t treat stderr like a log file, at least not by default.
  • Don’t print log level labels (ERR, WARN, etc.) or extraneous contextual information, unless in verbose mode.
  • Use a pager (e.g. less) if you are outputting a lot of text.


Errors

  • Catch errors and rewrite them for humans.
  • Signal-to-noise ratio is crucial.
  • Consider where the user will look first. 
  • If there is an unexpected or unexplainable error,
    provide debug and traceback information, and instructions on how to submit a bug.
  • Make it effortless to submit bug reports.


Arguments and flags

  • Prefer flags to args.
  • Have full-length versions of all flags. For example, have both -h and --help.
  • Only use one-letter flags for commonly used flags
  • If you’ve got two or more arguments for different things, you’re probably doing something wrong.
  • Make the default the right thing for most users.
  • Confirm before doing anything dangerous.
  • Do not read secrets directly from flags.
  • If possible, make arguments, flags and subcommands order-independent


Subcommands

  • Be consistent across subcommands. 
  • Use consistent names for multiple levels of subcommand.
  • Don’t have ambiguous or similarly-named commands. For example, having two subcommands called “update” and “upgrade” is quite confusing.


Robustness

  • Validate user input.
  • Responsive is more important than fast. Print something to the user in <100ms. If you’re making a network request, print something before you do it so it doesn’t hang and look broken.
  • Show progress if something takes a long time.
  • Do stuff in parallel where you can, but be thoughtful about it.
  • Make things time out.
  • Make it recoverable.
  • Make it crash-only.
  • This is the next step up from idempotence. If you can avoid needing to do any cleanup after operations, or you can defer that cleanup to the next run, your program can exit immediately on failure or interruption. This makes it both more robust and more responsive.


Future-proofing

  • Keep changes additive where you can. Rather than modify the behavior of a flag in a backwards-incompatible way.
  • Warn before you make a non-additive change.


Signals and control characters

  • If a user hits Ctrl-C (the INT signal), exit as soon as possible.
  • If a user hits Ctrl-C during clean-up operations that might take a long time, skip them. Tell the user what will happen when they hit Ctrl-C again, in case it is a destructive action.


Configuration
Environment variables
Naming

Distribution

  • If possible, distribute as a single binary.
  • Make it easy to uninstall.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.