Skip to content

Instantly share code, notes, and snippets.

@azriel91
Last active January 8, 2020 11:08
Show Gist options
  • Save azriel91/c99fbb897c1c11d5610b289dedfd3846 to your computer and use it in GitHub Desktop.
Save azriel91/c99fbb897c1c11d5610b289dedfd3846 to your computer and use it in GitHub Desktop.
Notes on how to write a good CLI application

How To Write A Good CLI Application

Modes

  • Interactive: For humans.
  • Non-interactive: For computers.

Interactive Mode

  • Print informatives to stderr.

  • Help text should include examples.

  • Help text should be coloured.

  • Long running commands should show progress.

  • Expect the command to be run twice 1000 times, at the same time.

    • Be able to continue where it left off.

      When processing 100000 items, crashing on the 7000th one is a valid scenario (OOM, out of disk space, network connection failed, server is down).

    • The user may not understand what went wrong, and run it again.

    • The user may understand what went wrong, and run it again.

  • Provide helpful messages to the user when the application panics.

    • Use colour.
    • Provide an error code.
    • What went wrong.
    • Why it went wrong (or possible scenarios).
    • How it can be remedied.
  • Link to a place to get help when there is an unknown error.

  • Collect and output errors at the end of execution.

    • When you don't know the error cause is printed above, you may not scroll up.
    • When you do know the error cause is printed above, it's annoying to scroll up.
  • Even better, output an execution report.

  • Handle Ctrl-C (SIGINT, not "copy").

  • Consider retrying automatically -- humans don't want to retry when the computer can.

  • Stop retrying automatically -- there's a time to give up.

Non Interactive Mode

  • Turn colour off by default, but allow it to be turned on.

    less -R re-renders colour, and the user might want that.

  • Print parsable output to stdout.

    Either:

    • line-by-line for streaming
    • Using a well defined format, e.g. json.
  • Return sensible exit codes

    • If there's a low number of error variants, use the exit code per error.
    • If there's a high number of error variants, use a parsable stdout message.

Logging

  • If the application is working as expected, then you may not want to log anything.
  • If the application is working as expected, but detects something unusual, then you may want to log something.
  • Log levels should be able to be passed in when the command is executed.
  • Log levels should be able to be passed in per logger.
  • Logs should be able to be directed to a file.log.
  • Consider using a log rotation policy (like renaming the previous logs, with a limit).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment