| # CLI tool help requirements | |
| ## Overview | |
| Command line help, as often provided through `--help` is an important means of | |
| communication with the user. It provides a shorthand for more detailed | |
| documentation and feature discovery. | |
| ## Guide | |
| Help documentation must include a usage section written in | |
| [Usage](#usage) format, followed by a brief descriptions about | |
| the command, and the following sections (as needed): | |
| * Options | |
| * Commands | |
| * Examples | |
| * Notes | |
| * Error codes | |
| ### Example | |
| Each section of this example is described in detail later in this document. | |
| (Note that `blast` is not a real tool). | |
| ```text | |
| Usage: blast [-f] [-s <scribble>] <command> [<args>] | |
| Destroy the contents of <file>. | |
| Options: | |
| -f force, ignore minor errors. This description | |
| is so long that it wraps to the next line. | |
| -s <scribble> write <scribble> repeatedly | |
| -v, --verbose say more. Defaults to $BLAST_VERBOSE. | |
| Commands: | |
| blow-up explosively separate | |
| grind make smaller by many small cuts | |
| help get help on other commands e.g. `blast help grind` | |
| Examples: | |
| Scribble 'abc' and then run |grind|. | |
| $ blast -s 'abc' grind old.txt taxes.cp | |
| Notes: | |
| Use `blast help <command>` for details on [<args>] for a subcommand. | |
| Error codes: | |
| 2 The blade is too dull. | |
| 3 Out of fuel. | |
| ``` | |
| #### General layout and style | |
| See above for an example that follows these requirements. | |
| Several sections call for **English prose**. This means writing in proper | |
| sentences using English grammar with US English spelling (as opposed to British | |
| English or others). Use one space between sentences, and adhere to the "Oxford | |
| comma" style. E.g. the Description and Notes sections are written in English | |
| prose. | |
| **Layout** | |
| - Each section is separated by one blank line. | |
| - Section contents are indented two spaces. | |
| - Single line contents will be written on the same line as the label with one | |
| space separating the colon and the command name. E.g. "`Usage: blast <file>`". | |
| - Multi-line sections will be written immediately following the label (without a | |
| blank line). Each line after the label will be indented two spaces. | |
| - All output is a single column of text with the exception of Options, Commands, | |
| and Error codes which are two column tables. | |
| - Use spaces for indentation or alignment. Do not output tab characters. | |
| - Wrap text at 80 columns. When wrapping Option or Command descriptions, align | |
| the subsequent lines with the start of the description (e.g. about 20 | |
| characters in). | |
| **Style** | |
| - Section titles appear in title-case: capitalize the first and last words. All | |
| words in between are also capitalized except for articles (a, an, the), | |
| conjunctions (e.g., and, but, or), and prepositions (e.g., on, in, with). | |
| - Short description fragments (the second column in Options or Commands) begin | |
| with a lowercase letter and are not expected to be full sentences. Any text | |
| beyond the short description should be complete sentences, with a period after | |
| the fragment. | |
| - Try to keep each section concise. If there is more to say, direct the user to | |
| use `--verbose` when running `--help` or direct them to the full | |
| documentation. | |
| - Unicode (UTF-8) characters are allowed in descriptive text (prose). The | |
| command name and usage text will only contain portable ASCII characters | |
| (without Unicode). | |
| ### Usage {:#usage} | |
| Usage is required and includes the "`Usage:`" header. | |
| ```text | |
| Usage: blast [-f] [-s <scribble>] <command> [<args>] | |
| ``` | |
| Usage will commonly be a single line, though multiple lines can be used to | |
| clarify when options are mutually exclusive. If the number of lines needed to | |
| present all the mutually exclusive scenarios becomes excessive, limit the lines | |
| to some common cases and give more details in the full docs. If there are many | |
| mutually exclusive options, consider making subcommands or separate tools to | |
| reduce the complexity. | |
| #### Usage syntax | |
| The command name is listed first. The command name is not hardcoded: it will be | |
| dynamically pulled from the command name, i.e. the last element on the `argv[0]` | |
| path. This allows a single binary to operate as multiple different tools. | |
| The name and usage text will contain portable ASCII characters only. All long | |
| form commands are entirely lowercase, i.e. never all-caps or mixed-case. Single | |
| letter switches should prefer lowercase, but uppercase is allowed. | |
| Use meaningful words for options and placeholders. Avoid abbreviations. Prefer | |
| single words. When more than one word is used, separate words with a hyphen | |
| (`-`), i.e. do not use underscores, camel-case, or run words together. | |
| Aside from the command name there are several kinds of arguments (as described | |
| in [Fuchsia Tool Requirements](http://go.corp.google.com/fuchsia-tool-requirements)). | |
| - Exact text | |
| - Arguments | |
| - Options (Switches and Keys) | |
| - Keyed options | |
| - Option delimiter | |
| ##### Exact text syntax | |
| Exact text is written as-is in the usage line. In the example "`Usage: copy | |
| <from> to <destination>`", the word `to` is required exact text. If exact text | |
| is optional, it will be enclosed in brackets (`[]`) in the usage line: "`Usage: | |
| copy <from> [to] <destination>`". | |
| ##### Argument syntax | |
| Arguments are enclosed in angle brackets (<>) to differentiate them from | |
| explicit text. In the example `Usage: copy <from> <destination>`, both `<from>` | |
| and `<destination>` are arguments. If an argument is optional, it will be | |
| enclosed in brackets (`[]`) such as: `Usage: copy <from> [<destination>]`. See | |
| also [Option Delimiter](./cli.md#option_delimiter). | |
| ##### Mutually exclusive option syntax | |
| There are a couple choices when illustrating mutually exclusive options. | |
| If more than one usage line is provided, each will show a mutually exclusive set | |
| of commands. For example: | |
| ```text | |
| Usage: | |
| swizzle [-z] <file> | |
| swizzle --reset | |
| ``` | |
| Indicates that `--reset` and usage with a `<file>` are mutually exclusive | |
| options. | |
| Another way to specify mutually exclusive options is using a vertical bar ('|') | |
| between the options. Note that when a vertical bar is used to indicate data flow | |
| between processes it is called a "Pipe." When used to separate options it is | |
| read as "Or". | |
| For example: | |
| ```text | |
| Usage: froth [-y|-z] <file> | |
| ``` | |
| Indicates that `-y` **_or_** `-z` switches can be used (or neither, since they | |
| are optional), but it's senseless to use both together (they are mutually | |
| exclusive options). To indicate that either value must be used, but not both, | |
| wrap the choices in parentheses, e.g. "`Usage: froth (-a|-b) <file>`" means that | |
| `-a` **_or_** `-b` must be passed. | |
| Note that it's common that `--version` or `--help` causes other arguments to be | |
| ignored and is seldom listed as such. Listing them as separate usage lines is | |
| considered unnecessary. | |
| ##### Grouping (implied) options | |
| There is no specific syntax to indicate when enabling one option will also | |
| affect another option. When an option implies that another option is enabled or | |
| disabled, specify that in the Options. E.g. "`passing -e implies -f`" means that | |
| if `-e` is enabled, `-f` will be enabled as if it were passed on the command | |
| line (regardless of whether `-f` was explicitly passed). The redundant passing | |
| of the implied value is harmless (not an error). | |
| Document the implication in the primary switch. E.g. if `-x implies -c and -p` | |
| place that note in the description of `-x` but not in `-c` and `-p`. This is to | |
| keep the `--help` output concise (this rule can be relaxed in the full | |
| documentation). | |
| ##### Optional keys | |
| To create the appearance of a keyed option with an optional Key, create optional | |
| exact text followed by an argument. For example "`Usage: copy [from] <from> [to] | |
| <destination>`". In the example, all of these are valid: "`copy a b`", "`copy | |
| from a b`", "`copy from a to b`", "`copy a to b`". | |
| ##### Repeating options | |
| If the same positional argument may be repeated, indicate that with an ellipsis | |
| ('...'). Rather than a Unicode ellipsis, use three consecutive periods. For | |
| example: "`Usage: copy <from> [<from>...] <to>`" means the last argument is | |
| always interpreted as the `<to>`, while the preceding values are multiple | |
| `<from>` entries. Note that "`<from> [<from>...]`" means there is one or more | |
| `<from>` entries, while "`Usage: copy [<from>...] <to>`" means zero or more | |
| `<from>` entries are accepted. | |
| For Key/Value pairs which may be repeated, group them with brackets (if the pair | |
| is optional) or parentheses (if the pair is not optional) and add an ellipsis to | |
| the group, e.g. `[--input <file>]...` or `(--input <file>)...` respectively. | |
| ##### Brackets | |
| Angle brackets (`<>`), brackets (`[]`), and parentheses (`()`) will not have | |
| spaces immediately inside. | |
| ```text | |
| [from] # correct | |
| <to> # correct | |
| (-a|-b) # correct | |
| [ from ] # incorrect | |
| < to > # incorrect | |
| ( -a|-b ) # incorrect | |
| ``` | |
| Angle brackets (<>) wrap Arguments or Key values. | |
| Brackets (`[]`) wrap optional elements. With nested angle brackets, such as | |
| `[<file>]`, interpret the `<file>` as an Argument that is optional. The nested | |
| "`[<`" is not a separate bracket style, it is a "`[`" with a "`<`" within it. | |
| When nesting, the brackets (`[`) will be outermost (do not use `<[file]>`). | |
| Parentheses (`()`) are used to group elements. Use parentheses when they improve | |
| clarity, such as with required mutually exclusive options. | |
| Braces (`{}`) are reserved for future use. This guide intentionally leaves open | |
| the possibility for braces to have special meaning in a future revision of this | |
| document. | |
| ### Description | |
| The description is required and does not include a header. I.e. the description | |
| area is not labeled "description". E.g. | |
| ```text | |
| Destroy the contents of <file>. | |
| ``` | |
| The description is written in US English prose (complete sentences using US | |
| English grammar, spelling, and punctuation). | |
| Every tool should tell you what it does and this is the section to do that. | |
| The Description section should describe | |
| - what the tool does (required) | |
| - the platform configuration used | |
| - schemes, data formats, or protocols used | |
| - golden workflows (critical developer journeys) | |
| - a broad URL to documentation (e.g. fuchsia.com/docs or similar, avoid deep | |
| links that go stale to easily) | |
| The Description section can also contain a "see also" referring to another tool | |
| by name (avoid using a URL). | |
| What not to put in the Description section | |
| - environment variables used, other than those already listed in Options | |
| (provide this in Options or Notes) | |
| - security hazards (explain these in the Notes section) | |
| - error codes (put those in an Error codes section) | |
| - copyright (don't include this in the `--help`) | |
| - author (don't include this in the `--help`) | |
| - how to get help on subcommands (put this in the short description for the | |
| `help` subcommand) | |
| - how to update the tool (that should be in the documentation for the tool | |
| package, if applicable) | |
| - release notes (use a separate file) | |
| ### Options | |
| An Options section is required if the program accepts arguments. E.g. | |
| ```text | |
| Options: | |
| -f force, ignore minor errors | |
| -s <scribble> write <scribble> repeatedly. Defaults to $BLAST_SCRIBBLE. | |
| ``` | |
| The listed options apply to the tool itself and not to a subcommand. Options for | |
| individual subcommands are listed when requesting help for that subcommand, e.g. | |
| when using `blast help grind` or `blast grind --help`. | |
| Try to keep options to a single, complete word. If two words are needed, | |
| separate the words with a hyphen (`-`). Avoid uncommon abbreviations. | |
| Present the list of options in alphabetical order. | |
| Options will list each argument, switch, and keyed option on separate lines with | |
| the exception of arguments that have both a short and long form. If an argument | |
| has both a short and long form they are listed on the same line, short form | |
| first, and separated by `, ` (comma space), e.g. `-f, --force`. | |
| Exact text arguments will not be listed in the Options section. They are shown | |
| in the Usage section. | |
| Text that will be typed as-is is not wrapped in brackets, while variable entries | |
| appear in angle brackets (`<>`) and optional entries appear in square brackets | |
| (`[]`). When listing options, the Key is never optional. For example: | |
| ```text | |
| -a a good example | |
| [-b] a bad example, to use -b it must be typed as-is | |
| ``` | |
| A short description will follow each option. There's no limit on the length of | |
| this description, but be concise. Try to put more details in the overall tool | |
| description, the Examples, or the Notes instead of creating a lengthy option | |
| description. | |
| What to describe | |
| - a brief reminder of what the option implies, e.g. `ignore minor errors` | |
| - if the option overrides another option, e.g. `-x implies -c and -p` | |
| - default value, e.g. `defaults to $BLAST_SCRIBBLE` | |
| The column on which the description sentence fragment begins may vary depending | |
| on the needs of the tool. Use 20 characters from the left edge if it looks okay, | |
| but adjust if a bit more or less reads better. | |
| If there is a large number of options, consider showing a useful subset and | |
| explaining how to get further help to see all of them, e.g. by passing | |
| `--verbose` along with `--help`. | |
| ### Commands | |
| A commands section is required if the program has subcommands. If present it | |
| will be labeled, "Commands:". E.g. | |
| ```text | |
| Commands: | |
| blow-up explosively separate | |
| grind make smaller by many small cuts | |
| help get help on other commands e.g. `blast help grind` | |
| ``` | |
| If the program does not have subcommands, the commands section will not be | |
| present. | |
| When a tool has subcommands, it will also have a `help` command to get further | |
| help on the subcommands, i.e.` blast help grind`. | |
| Try to keep subcommands to a single, complete word. If two words are needed, | |
| separate the words with a hyphen (`-`). Avoid uncommon abbreviations. Present | |
| the list of commands in alphabetical order. | |
| Each command name appears with a short description on a separate line. For a | |
| more lengthy command description, the user will specifically ask for help on | |
| that command. This description serves as a short reminder of the command and to | |
| assist in discovery of commands. | |
| If there is a large number of commands, consider showing a useful subset and | |
| explaining how to get further help to see all of them, e.g. by passing | |
| `--verbose` along with `--help`. | |
| ### Examples | |
| An examples section is optional. If present it will be labeled, "Examples:". | |
| E.g. | |
| ```text | |
| Examples: | |
| Scribble 'abc' and then run |grind|. | |
| $ blast -s 'abc' grind old.txt taxes.cp | |
| ``` | |
| Each example will have US English prose (i.e. complete sentences using US | |
| English grammar, spelling, and punctuation) describing the example, followed by | |
| an example command line. Each line that would be entered on the command line | |
| literally will be prefixed with a "`$ `" to mimic a command prompt. | |
| To wrap an example that is overly long, end the previous line with "`\ `" and | |
| begin subsequent lines with "` `" (spaces) to indicate line continuation. | |
| ```text | |
| This example wraps onto multiple lines. | |
| $ blast -s 2332 some/long/path/cats.o \ | |
| more/long/path/dogs.o more/long/path/bears.o \ | |
| more/long/path/deer.o | |
| ``` | |
| If it is helpful to show some of the output from the example command, write the | |
| output immediately following the example. | |
| Separate examples with one blank line. | |
| If the Examples section is getting overly long, move examples to a help doc. | |
| Interactive help examples are for quick reference and discoverability rather | |
| than exhaustive documentation. | |
| ### Notes | |
| Notes are optional and begin with a "Notes:" header. E.g. | |
| ```text | |
| Notes: | |
| Use `blast help <command>` for details on [<args>] for a subcommand. | |
| ``` | |
| The notes are written in US English prose (i.e. complete sentences using US | |
| English grammar, spelling, and punctuation). | |
| What to put in the Notes | |
| - environment variables used, other than those already listed in Options (for | |
| default values) | |
| - security hazards | |
| - reminders to help the user | |
| What not to put in the Notes | |
| - error codes (put those in an Error codes section) | |
| - copyright (don't include this in the `--help`) | |
| - author (don't include this in the `--help`) | |
| - how to get help on subcommands (put this in the short description for the | |
| `help` subcommand) | |
| - how to update the tool (that should be in the documentation for the tool | |
| package, if applicable) | |
| - release notes (use a separate file) | |
| ### Error codes | |
| The Error codes section is required if codes other than `0` or `1` are | |
| generated. E.g. | |
| ```text | |
| Error codes: | |
| 2 The blade is too dull. | |
| 3 Out of fuel. | |
| ``` | |
| This section is omitted if only `0` or `1` results are generated by the program. | |
| Error code `0` is always treated as "no error" and error code `1` is always a | |
| "general error". Neither are documented in the `--help` output. Every error code | |
| other than `0` or `1` that may be generated by the tool must be documented. | |
| ### Platform specifics | |
| Some platforms (e.g. DOS) use a different option prefix (e.g. `/`) or may allow | |
| case insensitive switches. Tools will use a dash prefix (`-`) and case sensitive | |
| options regardless of the platform. This means that the documentation for a tool | |
| generally doesn't need to consider the platform being used. | |
| ### What not to include in --help output | |
| Do not show Key/Value pairs with an equals sign (`=`), e.g. `--scribble=abc`. | |
| The Key and Value are parsed using whitespace as a delimiter (`--scribble abc`). | |
| Showing the equals in the help is potentially confusing. | |
| Do not implement a pager (something like the `more` program that pauses output | |
| on each screenful of text). | |
| Do not include | |
| - A copyright in the help output (put that where legal specifies). | |
| - Release notes (put that in release notes). | |
| - Full documentation (put that in the markdown documentation). | |
| - Version information (output that from `--version`). | |
| - Documentation on result codes `0` or `1` (put in .md docs). | |
| - Shell-specific help (such as how to redirect output or pipe to a pager). |