fix(help): Shift focus to subcommands, when present

In surveying various tools and CLI parsers, I noticed they list the
subcommands first.  This puts an emphasis on them which makes sense
because that is most likely what an end user is supposed to pass in
next.

Listing them last aligns with the usage order but it probably doesn't
outweigh the value of getting a user moving forward.
This commit is contained in:
Ed Page 2022-08-26 10:59:27 -05:00
parent aacb5620f1
commit 83d6add9aa
22 changed files with 155 additions and 151 deletions

View file

@ -85,6 +85,7 @@ MSRV is now 1.60.0
- *(help)* Show when a flag is `ArgAction::Count` by adding an `...`
- *(help)* Use a more neutral palette for coloring
- *(help)* Don't rely on ALL CAPS for help headers
- *(help)* List subcommands first, focusing the emphasis on them
- *(version)* Use `Command::display_name` rather than `Command::bin_name`
- *(parser)* Assert on unknown args when using external subcommands (#3703)
- *(parser)* Always fill in `""` argument for external subcommands (#3263)

View file

@ -11,13 +11,13 @@ cargo
Usage:
cargo <SUBCOMMAND>
Options:
-h, --help Print help information
Subcommands:
example-derive A simple to use, efficient, and full-featured Command Line Argument Parser
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help information
$ cargo-example-derive example-derive --help
cargo-example-derive [..]
A simple to use, efficient, and full-featured Command Line Argument Parser

View file

@ -11,13 +11,13 @@ cargo
Usage:
cargo <SUBCOMMAND>
Options:
-h, --help Print help information
Subcommands:
example A simple to use, efficient, and full-featured Command Line Argument Parser
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help information
$ cargo-example example --help
cargo-example [..]
A simple to use, efficient, and full-featured Command Line Argument Parser

View file

@ -106,15 +106,15 @@ clap
Usage:
interop_hand_subcommand[EXE] [OPTIONS] <SUBCOMMAND>
Options:
-t, --top-level
-h, --help Print help information
Subcommands:
add
remove
help Print this message or the help of the given subcommand(s)
Options:
-t, --top-level
-h, --help Print help information
```
```console

View file

@ -12,9 +12,6 @@ A fictional versioning CLI
Usage:
git-derive[EXE] <SUBCOMMAND>
Options:
-h, --help Print help information
Subcommands:
clone Clones repos
push pushes things
@ -22,6 +19,9 @@ Subcommands:
stash
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help information
$ git-derive help
git
A fictional versioning CLI
@ -29,9 +29,6 @@ A fictional versioning CLI
Usage:
git-derive[EXE] <SUBCOMMAND>
Options:
-h, --help Print help information
Subcommands:
clone Clones repos
push pushes things
@ -39,6 +36,9 @@ Subcommands:
stash
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help information
$ git-derive help add
git-add
adds things
@ -84,16 +84,16 @@ Usage:
git-derive[EXE] stash [OPTIONS]
git-derive[EXE] stash <SUBCOMMAND>
Options:
-m, --message <MESSAGE>
-h, --help Print help information
Subcommands:
push
pop
apply
help Print this message or the help of the given subcommand(s)
Options:
-m, --message <MESSAGE>
-h, --help Print help information
$ git-derive stash push -h
git-stash-push

View file

@ -10,9 +10,6 @@ A fictional versioning CLI
Usage:
git[EXE] <SUBCOMMAND>
Options:
-h, --help Print help information
Subcommands:
clone Clones repos
push pushes things
@ -20,6 +17,9 @@ Subcommands:
stash
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help information
$ git help
git
A fictional versioning CLI
@ -27,9 +27,6 @@ A fictional versioning CLI
Usage:
git[EXE] <SUBCOMMAND>
Options:
-h, --help Print help information
Subcommands:
clone Clones repos
push pushes things
@ -37,6 +34,9 @@ Subcommands:
stash
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help information
$ git help add
git-add
adds things
@ -82,16 +82,16 @@ Usage:
git[EXE] stash [OPTIONS]
git[EXE] stash <SUBCOMMAND>
Options:
-m, --message <MESSAGE>
-h, --help Print help information
Subcommands:
push
pop
apply
help Print this message or the help of the given subcommand(s)
Options:
-m, --message <MESSAGE>
-h, --help Print help information
$ git stash push -h
git-stash-push

View file

@ -30,13 +30,13 @@ busybox
Usage:
busybox [OPTIONS] [APPLET]
Options:
--install <install> Install hardlinks for all subcommands in path
-h, --help Print help information
APPLETS:
true does nothing successfully
false does nothing unsuccessfully
help Print this message or the help of the given subcommand(s)
Options:
--install <install> Install hardlinks for all subcommands in path
-h, --help Print help information
```

View file

@ -42,15 +42,15 @@ package manager utility
Usage:
pacman[EXE] <SUBCOMMAND>
Options:
-h, --help Print help information
-V, --version Print version information
Subcommands:
query -Q --query Query the package database.
sync -S --sync Synchronize packages.
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help information
-V, --version Print version information
$ pacman -S -h
pacman-sync
Synchronize packages.

View file

@ -6,6 +6,10 @@ A simple to use, efficient, and full-featured Command Line Argument Parser
Usage:
01_quick[EXE] [OPTIONS] [name] [SUBCOMMAND]
Subcommands:
test does testing things
help Print this message or the help of the given subcommand(s)
Arguments:
<name> Optional name to operate on
@ -15,10 +19,6 @@ Options:
-h, --help Print help information
-V, --version Print version information
Subcommands:
test does testing things
help Print this message or the help of the given subcommand(s)
```
By default, the program does nothing:

View file

@ -6,14 +6,14 @@ A simple to use, efficient, and full-featured Command Line Argument Parser
Usage:
03_04_subcommands[EXE] <SUBCOMMAND>
Options:
-h, --help Print help information
-V, --version Print version information
Subcommands:
add Adds files to myapp
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help information
-V, --version Print version information
$ 03_04_subcommands help add
clap-add [..]
Adds files to myapp
@ -43,14 +43,14 @@ A simple to use, efficient, and full-featured Command Line Argument Parser
Usage:
03_04_subcommands[EXE] <SUBCOMMAND>
Options:
-h, --help Print help information
-V, --version Print version information
Subcommands:
add Adds files to myapp
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help information
-V, --version Print version information
```
Because we set [`Command::propagate_version`][crate::Command::propagate_version]:

View file

@ -6,6 +6,10 @@ A simple to use, efficient, and full-featured Command Line Argument Parser
Usage:
01_quick_derive[EXE] [OPTIONS] [NAME] [SUBCOMMAND]
Subcommands:
test does testing things
help Print this message or the help of the given subcommand(s)
Arguments:
<NAME> Optional name to operate on
@ -15,10 +19,6 @@ Options:
-h, --help Print help information
-V, --version Print version information
Subcommands:
test does testing things
help Print this message or the help of the given subcommand(s)
```
By default, the program does nothing:

View file

@ -6,14 +6,14 @@ A simple to use, efficient, and full-featured Command Line Argument Parser
Usage:
03_04_subcommands_derive[EXE] <SUBCOMMAND>
Options:
-h, --help Print help information
-V, --version Print version information
Subcommands:
add Adds files to myapp
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help information
-V, --version Print version information
$ 03_04_subcommands_derive help add
clap-add [..]
Adds files to myapp
@ -43,14 +43,14 @@ A simple to use, efficient, and full-featured Command Line Argument Parser
Usage:
03_04_subcommands_derive[EXE] <SUBCOMMAND>
Options:
-h, --help Print help information
-V, --version Print version information
Subcommands:
add Adds files to myapp
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help information
-V, --version Print version information
```
Because we added `#[clap(propagate_version = true)]`:

View file

@ -338,22 +338,41 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
.filter_map(|arg| arg.get_help_heading())
.collect::<FlatSet<_>>();
let mut first = if !pos.is_empty() {
let mut first = true;
if subcmds {
if !first {
self.none("\n\n");
}
first = false;
let default_help_heading = Str::from("Subcommands");
self.header(
self.cmd
.get_subcommand_help_heading()
.unwrap_or(&default_help_heading),
);
self.header(":\n");
self.write_subcommands(self.cmd);
}
if !pos.is_empty() {
if !first {
self.none("\n\n");
}
first = false;
// Write positional args if any
self.header("Arguments:\n");
self.write_args(&pos, "Arguments", positional_sort_key);
false
} else {
true
};
}
if !non_pos.is_empty() {
if !first {
self.none("\n\n");
}
first = false;
self.header("Options:\n");
self.write_args(&non_pos, "Options", option_sort_key);
first = false;
}
if !custom_headings.is_empty() {
for heading in custom_headings {
@ -373,28 +392,12 @@ impl<'cmd, 'writer> Help<'cmd, 'writer> {
if !first {
self.none("\n\n");
}
first = false;
self.header(format!("{}:\n", heading));
self.write_args(&args, heading, option_sort_key);
first = false
}
}
}
if subcmds {
if !first {
self.none("\n\n");
}
let default_help_heading = Str::from("Subcommands");
self.header(
self.cmd
.get_subcommand_help_heading()
.unwrap_or(&default_help_heading),
);
self.header(":\n");
self.write_subcommands(self.cmd);
}
}
/// Sorts arguments by length and display order and write their help to the wrapped stream.
fn write_args(&mut self, args: &[&Arg], _category: &str, sort_key: ArgSortKey) {

View file

@ -271,14 +271,14 @@ fn subcommand_sorted_display_order() {
Usage:
test [SUBCOMMAND]
Options:
-h, --help Print help information
-V, --version Print version information
Subcommands:
a1 blah a1
b1 blah b1
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help information
-V, --version Print version information
";
let app_subcmd_alpha_order = Command::new("test")
@ -308,14 +308,14 @@ fn subcommand_derived_display_order() {
Usage:
test [SUBCOMMAND]
Options:
-h, --help Print help information
-V, --version Print version information
Subcommands:
b1 blah b1
a1 blah a1
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help information
-V, --version Print version information
";
let app_subcmd_decl_order = Command::new("test").version("1").subcommands(vec![

View file

@ -14,12 +14,12 @@ fn very_large_display_order() {
Usage:
test [SUBCOMMAND]
Options:
-h, --help Print help information
Subcommands:
help Print this message or the help of the given subcommand(s)
sub
Options:
-h, --help Print help information
",
false,
);

View file

@ -207,6 +207,10 @@ tests clap library
Usage:
clap-test [OPTIONS] [ARGS] [SUBCOMMAND]
Subcommands:
subcmd tests subcommands
help Print this message or the help of the given subcommand(s)
Arguments:
<positional> tests positionals
<positional2> tests positionals with exclusions
@ -226,10 +230,6 @@ Options:
--optvalnoeq [<optval>] Tests optional value
-h, --help Print help information
-V, --version Print version information
Subcommands:
subcmd tests subcommands
help Print this message or the help of the given subcommand(s)
";
utils::assert_output(utils::complex_app(), "clap-test --help", HELP, false);
@ -1103,6 +1103,10 @@ Usage:
prog --opt <FILE> [PATH]
prog [PATH] <SUBCOMMAND>
Subcommands:
test
help Print this message or the help of the given subcommand(s)
Arguments:
<PATH> help
@ -1110,10 +1114,6 @@ Options:
-o, --opt <FILE> tests options
-h, --help Print help information
-V, --version Print version information
Subcommands:
test
help Print this message or the help of the given subcommand(s)
";
let cmd = Command::new("prog")
@ -1155,6 +1155,10 @@ Usage:
prog [OPTIONS] [PATH]
prog <SUBCOMMAND>
Subcommands:
test
help Print this message or the help of the given subcommand(s)
Arguments:
<PATH> help
@ -1163,10 +1167,6 @@ Options:
-o, --opt <FILE> tests options
-h, --help Print help information
-V, --version Print version information
Subcommands:
test
help Print this message or the help of the given subcommand(s)
";
let cmd = Command::new("prog")
@ -1399,6 +1399,10 @@ Usage:
last <TARGET> [CORPUS] -- <ARGS>...
last <SUBCOMMAND>
Subcommands:
test some
help Print this message or the help of the given subcommand(s)
Arguments:
<TARGET> some
<CORPUS> some
@ -1407,10 +1411,6 @@ Arguments:
Options:
-h, --help Print help information
-V, --version Print version information
Subcommands:
test some
help Print this message or the help of the given subcommand(s)
";
let cmd = Command::new("last")
@ -1438,6 +1438,10 @@ Usage:
last <TARGET> [CORPUS] [-- <ARGS>...]
last <SUBCOMMAND>
Subcommands:
test some
help Print this message or the help of the given subcommand(s)
Arguments:
<TARGET> some
<CORPUS> some
@ -1446,10 +1450,6 @@ Arguments:
Options:
-h, --help Print help information
-V, --version Print version information
Subcommands:
test some
help Print this message or the help of the given subcommand(s)
";
let cmd = Command::new("last")
@ -2139,12 +2139,12 @@ fn prefer_about_over_long_about_in_subcommands_list() {
Usage:
about-in-subcommands-list [SUBCOMMAND]
Options:
-h, --help Print help information
Subcommands:
sub short about sub
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help information
";
let cmd = Command::new("about-in-subcommands-list").subcommand(

View file

@ -7,13 +7,13 @@ static VISIBLE_ALIAS_HELP: &str = "clap-test 2.6
Usage:
clap-test [SUBCOMMAND]
Options:
-h, --help Print help information
-V, --version Print version information
Subcommands:
test Some help [aliases: dongle, done]
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help information
-V, --version Print version information
";
static INVISIBLE_ALIAS_HELP: &str = "clap-test 2.6
@ -21,13 +21,13 @@ static INVISIBLE_ALIAS_HELP: &str = "clap-test 2.6
Usage:
clap-test [SUBCOMMAND]
Options:
-h, --help Print help information
-V, --version Print version information
Subcommands:
test Some help
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help information
-V, --version Print version information
";
#[cfg(feature = "suggestions")]

View file

@ -51,6 +51,10 @@ Does awesome things
Usage:
MyApp [OPTIONS] <output> [SUBCOMMAND]
Subcommands:
test does testing things
help Print this message or the help of the given subcommand(s)
Arguments:
<output> Sets an optional output file
@ -59,10 +63,6 @@ Options:
-d... Turn debugging information on
-h, --help Print help information
-V, --version Print version information
Subcommands:
test does testing things
help Print this message or the help of the given subcommand(s)
";
#[test]

View file

@ -8,12 +8,12 @@ stdio-fixture 1.0
Usage:
stdio-fixture[EXE] [OPTIONS] [SUBCOMMAND]
Subcommands:
more
help Print this message or the help of the given subcommand(s)
Options:
--verbose log
-h, --help Print help information
-V, --version Print version information
Subcommands:
more
help Print this message or the help of the given subcommand(s)
"""

View file

@ -7,13 +7,13 @@ stdio-fixture 1.0
Usage:
stdio-fixture[EXE] [OPTIONS] [SUBCOMMAND]
Subcommands:
more
help Print this message or the help of the given subcommand(s)
Options:
--verbose log
-h, --help Print help information
-V, --version Print version information
Subcommands:
more
help Print this message or the help of the given subcommand(s)
"""
stderr = ""

View file

@ -7,6 +7,12 @@ stdio-fixture 1.0
Usage:
stdio-fixture[EXE] [OPTIONS] [SUBCOMMAND]
Subcommands:
more
help
Print this message or the help of the given subcommand(s)
Options:
--verbose
more log
@ -16,11 +22,5 @@ Options:
-V, --version
Print version information
Subcommands:
more
help
Print this message or the help of the given subcommand(s)
"""
stderr = ""

View file

@ -7,6 +7,12 @@ stdio-fixture 1.0
Usage:
stdio-fixture[EXE] [OPTIONS] [SUBCOMMAND]
Subcommands:
more
help
Print this message or the help of the given subcommand(s)
Options:
--verbose
more log
@ -16,11 +22,5 @@ Options:
-V, --version
Print version information
Subcommands:
more
help
Print this message or the help of the given subcommand(s)
"""
stderr = ""