fix(help): Subcommand display order respects Command::next_display_order

Previous behavior:
- They'd be sorted by default
- They'd derive display order if `DeriveDisplayOrder` was set
  - This could be set recursively
- The initial display order value for subcommands was 0

New behavior:
- Sorted order is derived by default
- Sorting is turned on by `cmd.next_display_order(None)`
  - This is not recursive, it must be set on each level
- The display order incrementing is mixed with arguments
  - This does make it slightly more difficult to predict
This commit is contained in:
Ed Page 2022-07-22 14:58:27 -05:00
parent ce8ebe1ccc
commit 389ff4ff21
17 changed files with 117 additions and 106 deletions

View file

@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- `ErrorKind::EmptyValue` replaced with `ErrorKind::InvalidValue` - `ErrorKind::EmptyValue` replaced with `ErrorKind::InvalidValue`
- `ErrorKind::UnrecognizedSubcommand` replaced with `ErrorKind::InvalidSubcommand` - `ErrorKind::UnrecognizedSubcommand` replaced with `ErrorKind::InvalidSubcommand`
- `arg!` now sets `ArgAction::SetTrue`, `ArgAction::Count`, `ArgAction::Set`, or `ArgAction::Append` as appropriate - `arg!` now sets `ArgAction::SetTrue`, `ArgAction::Count`, `ArgAction::Set`, or `ArgAction::Append` as appropriate
- *(help)* Subcommand display order respects `Command::next_display_order` instead of `DeriveDisplayOrder` and using its own initial display order value
- *(env)* Parse `--help` and `--version` like any `ArgAction::SetTrue` flag - *(env)* Parse `--help` and `--version` like any `ArgAction::SetTrue` flag
- *(derive)* `subcommand_required(true).arg_required_else_help(true)` is set instead of `SubcommandRequiredElseHelp` - *(derive)* `subcommand_required(true).arg_required_else_help(true)` is set instead of `SubcommandRequiredElseHelp`

View file

@ -112,8 +112,8 @@ OPTIONS:
SUBCOMMANDS: SUBCOMMANDS:
add add
help Print this message or the help of the given subcommand(s)
remove remove
help Print this message or the help of the given subcommand(s)
``` ```

View file

@ -16,11 +16,11 @@ OPTIONS:
-h, --help Print help information -h, --help Print help information
SUBCOMMANDS: SUBCOMMANDS:
add adds things
clone Clones repos clone Clones repos
help Print this message or the help of the given subcommand(s)
push pushes things push pushes things
add adds things
stash stash
help Print this message or the help of the given subcommand(s)
$ git-derive help $ git-derive help
git git
@ -33,11 +33,11 @@ OPTIONS:
-h, --help Print help information -h, --help Print help information
SUBCOMMANDS: SUBCOMMANDS:
add adds things
clone Clones repos clone Clones repos
help Print this message or the help of the given subcommand(s)
push pushes things push pushes things
add adds things
stash stash
help Print this message or the help of the given subcommand(s)
$ git-derive help add $ git-derive help add
git-add git-add
@ -89,10 +89,10 @@ OPTIONS:
-m, --message <MESSAGE> -m, --message <MESSAGE>
SUBCOMMANDS: SUBCOMMANDS:
push
pop
apply apply
help Print this message or the help of the given subcommand(s) help Print this message or the help of the given subcommand(s)
pop
push
$ git-derive stash push -h $ git-derive stash push -h
git-stash-push git-stash-push

View file

@ -14,11 +14,11 @@ OPTIONS:
-h, --help Print help information -h, --help Print help information
SUBCOMMANDS: SUBCOMMANDS:
add adds things
clone Clones repos clone Clones repos
help Print this message or the help of the given subcommand(s)
push pushes things push pushes things
add adds things
stash stash
help Print this message or the help of the given subcommand(s)
$ git help $ git help
git git
@ -31,11 +31,11 @@ OPTIONS:
-h, --help Print help information -h, --help Print help information
SUBCOMMANDS: SUBCOMMANDS:
add adds things
clone Clones repos clone Clones repos
help Print this message or the help of the given subcommand(s)
push pushes things push pushes things
add adds things
stash stash
help Print this message or the help of the given subcommand(s)
$ git help add $ git help add
git-add git-add
@ -87,10 +87,10 @@ OPTIONS:
-m, --message <MESSAGE> -m, --message <MESSAGE>
SUBCOMMANDS: SUBCOMMANDS:
push
pop
apply apply
help Print this message or the help of the given subcommand(s) help Print this message or the help of the given subcommand(s)
pop
push
$ git stash push -h $ git stash push -h
git-stash-push git-stash-push

View file

@ -35,8 +35,8 @@ OPTIONS:
--install <install> Install hardlinks for all subcommands in path --install <install> Install hardlinks for all subcommands in path
APPLETS: APPLETS:
true does nothing successfully
false does nothing unsuccessfully false does nothing unsuccessfully
help Print this message or the help of the given subcommand(s) help Print this message or the help of the given subcommand(s)
true does nothing successfully
``` ```

View file

@ -47,9 +47,9 @@ OPTIONS:
-V, --version Print version information -V, --version Print version information
SUBCOMMANDS: SUBCOMMANDS:
help Print this message or the help of the given subcommand(s)
query -Q --query Query the package database. query -Q --query Query the package database.
sync -S --sync Synchronize packages. sync -S --sync Synchronize packages.
help Print this message or the help of the given subcommand(s)
$ pacman -S -h $ pacman -S -h
pacman-sync pacman-sync

View file

@ -16,8 +16,8 @@ OPTIONS:
-V, --version Print version information -V, --version Print version information
SUBCOMMANDS: SUBCOMMANDS:
help Print this message or the help of the given subcommand(s)
test does testing things test does testing things
help Print this message or the help of the given subcommand(s)
``` ```

View file

@ -16,8 +16,8 @@ OPTIONS:
-V, --version Print version information -V, --version Print version information
SUBCOMMANDS: SUBCOMMANDS:
help Print this message or the help of the given subcommand(s)
test does testing things test does testing things
help Print this message or the help of the given subcommand(s)
``` ```

View file

@ -402,7 +402,13 @@ impl<'help> Command<'help> {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn subcommand<S: Into<Self>>(mut self, subcmd: S) -> Self { pub fn subcommand<S: Into<Self>>(mut self, subcmd: S) -> Self {
self.subcommands.push(subcmd.into()); let mut subcmd = subcmd.into();
if let Some(current_disp_ord) = self.current_disp_ord.as_mut() {
let current = *current_disp_ord;
subcmd.disp_ord.get_or_insert(current);
*current_disp_ord = current + 1;
}
self.subcommands.push(subcmd);
self self
} }
@ -426,8 +432,12 @@ impl<'help> Command<'help> {
I: IntoIterator<Item = T>, I: IntoIterator<Item = T>,
T: Into<Self>, T: Into<Self>,
{ {
for subcmd in subcmds.into_iter() { let subcmds = subcmds.into_iter();
self.subcommands.push(subcmd.into()); let (lower, _) = subcmds.size_hint();
self.subcommands.reserve(lower);
for subcmd in subcmds {
self = self.subcommand(subcmd);
} }
self self
} }
@ -4378,9 +4388,6 @@ To change `help`s short, call `cmd.arg(Arg::new(\"help\")...)`.",
{ {
a.disp_ord.make_explicit(); a.disp_ord.make_explicit();
} }
for (i, sc) in &mut self.subcommands.iter_mut().enumerate() {
sc.disp_ord.get_or_insert(i);
}
} }
for sc in &mut self.subcommands { for sc in &mut self.subcommands {
sc._derive_display_order(); sc._derive_display_order();

View file

@ -291,3 +291,74 @@ fn prefer_user_help_in_subcommand_with_derive_order() {
false, false,
); );
} }
#[test]
fn subcommand_sorted_display_order() {
static SUBCMD_ALPHA_ORDER: &str = "test 1
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)
";
let app_subcmd_alpha_order = Command::new("test")
.version("1")
.next_display_order(None)
.subcommands(vec![
Command::new("b1")
.about("blah b1")
.arg(Arg::new("test").short('t')),
Command::new("a1")
.about("blah a1")
.arg(Arg::new("roster").short('r')),
]);
utils::assert_output(
app_subcmd_alpha_order,
"test --help",
SUBCMD_ALPHA_ORDER,
false,
);
}
#[test]
fn subcommand_derived_display_order() {
static SUBCMD_DECL_ORDER: &str = "test 1
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)
";
let app_subcmd_decl_order = Command::new("test").version("1").subcommands(vec![
Command::new("b1")
.about("blah b1")
.arg(Arg::new("test").short('t')),
Command::new("a1")
.about("blah a1")
.arg(Arg::new("roster").short('r')),
]);
utils::assert_output(
app_subcmd_decl_order,
"test --help",
SUBCMD_DECL_ORDER,
false,
);
}

View file

@ -43,8 +43,8 @@ OPTIONS:
-V, --version Print version information -V, --version Print version information
SUBCOMMANDS: SUBCOMMANDS:
help Print this message or the help of the given subcommand(s)
subcmd tests subcommands subcmd tests subcommands
help Print this message or the help of the given subcommand(s)
"; ";
static SC_NEGATES_REQS: &str = "prog 1.0 static SC_NEGATES_REQS: &str = "prog 1.0
@ -62,8 +62,8 @@ OPTIONS:
-V, --version Print version information -V, --version Print version information
SUBCOMMANDS: SUBCOMMANDS:
help Print this message or the help of the given subcommand(s)
test test
help Print this message or the help of the given subcommand(s)
"; ";
static ARGS_NEGATE_SC: &str = "prog 1.0 static ARGS_NEGATE_SC: &str = "prog 1.0
@ -82,8 +82,8 @@ OPTIONS:
-V, --version Print version information -V, --version Print version information
SUBCOMMANDS: SUBCOMMANDS:
help Print this message or the help of the given subcommand(s)
test test
help Print this message or the help of the given subcommand(s)
"; ";
static AFTER_HELP: &str = "some text that comes before the help static AFTER_HELP: &str = "some text that comes before the help
@ -410,8 +410,8 @@ OPTIONS:
-V, --version Print version information -V, --version Print version information
SUBCOMMANDS: SUBCOMMANDS:
help Print this message or the help of the given subcommand(s)
test some test some
help Print this message or the help of the given subcommand(s)
"; ";
static LAST_ARG_REQ: &str = "last 0.1 static LAST_ARG_REQ: &str = "last 0.1
@ -445,8 +445,8 @@ OPTIONS:
-V, --version Print version information -V, --version Print version information
SUBCOMMANDS: SUBCOMMANDS:
help Print this message or the help of the given subcommand(s)
test some test some
help Print this message or the help of the given subcommand(s)
"; ";
static HIDE_DEFAULT_VAL: &str = "default 0.1 static HIDE_DEFAULT_VAL: &str = "default 0.1
@ -602,8 +602,8 @@ OPTIONS:
-h, --help Print help information -h, --help Print help information
SUBCOMMANDS: SUBCOMMANDS:
help Print this message or the help of the given subcommand(s)
sub short about sub sub short about sub
help Print this message or the help of the given subcommand(s)
"; ";
fn setup() -> Command<'static> { fn setup() -> Command<'static> {

View file

@ -12,8 +12,8 @@ OPTIONS:
-V, --version Print version information -V, --version Print version information
SUBCOMMANDS: SUBCOMMANDS:
help Print this message or the help of the given subcommand(s)
test Some help [aliases: dongle, done] test Some help [aliases: dongle, done]
help Print this message or the help of the given subcommand(s)
"; ";
static INVISIBLE_ALIAS_HELP: &str = "clap-test 2.6 static INVISIBLE_ALIAS_HELP: &str = "clap-test 2.6
@ -26,37 +26,7 @@ OPTIONS:
-V, --version Print version information -V, --version Print version information
SUBCOMMANDS: SUBCOMMANDS:
help Print this message or the help of the given subcommand(s)
test Some help test Some help
";
static SUBCMD_ALPHA_ORDER: &str = "test 1
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)
";
static SUBCMD_DECL_ORDER: &str = "test 1
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) help Print this message or the help of the given subcommand(s)
"; ";
@ -169,44 +139,6 @@ fn subcommand_multiple() {
); );
} }
#[test]
fn subcommand_display_order() {
let app_subcmd_alpha_order = Command::new("test").version("1").subcommands(vec![
Command::new("b1")
.about("blah b1")
.arg(Arg::new("test").short('t')),
Command::new("a1")
.about("blah a1")
.arg(Arg::new("roster").short('r')),
]);
utils::assert_output(
app_subcmd_alpha_order,
"test --help",
SUBCMD_ALPHA_ORDER,
false,
);
let app_subcmd_decl_order = Command::new("test")
.version("1")
.setting(clap::AppSettings::DeriveDisplayOrder)
.subcommands(vec![
Command::new("b1")
.about("blah b1")
.arg(Arg::new("test").short('t')),
Command::new("a1")
.about("blah a1")
.arg(Arg::new("roster").short('r')),
]);
utils::assert_output(
app_subcmd_decl_order,
"test --help",
SUBCMD_DECL_ORDER,
false,
);
}
#[test] #[test]
fn single_alias() { fn single_alias() {
let m = Command::new("myprog") let m = Command::new("myprog")

View file

@ -40,8 +40,8 @@ OPTIONS:
ARGS: ARGS:
<output> Sets an optional output file <output> Sets an optional output file
SUBCOMMANDS: SUBCOMMANDS:
help Print this message or the help of the given subcommand(s)
test does testing things test does testing things
help Print this message or the help of the given subcommand(s)
"; ";
static SIMPLE_TEMPLATE: &str = "MyApp 1.0 static SIMPLE_TEMPLATE: &str = "MyApp 1.0
@ -61,8 +61,8 @@ OPTIONS:
-V, --version Print version information -V, --version Print version information
SUBCOMMANDS: SUBCOMMANDS:
help Print this message or the help of the given subcommand(s)
test does testing things test does testing things
help Print this message or the help of the given subcommand(s)
"; ";
#[test] #[test]

View file

@ -14,6 +14,6 @@ OPTIONS:
--verbose log --verbose log
SUBCOMMANDS: SUBCOMMANDS:
help Print this message or the help of the given subcommand(s)
more more
help Print this message or the help of the given subcommand(s)
""" """

View file

@ -13,7 +13,7 @@ OPTIONS:
--verbose log --verbose log
SUBCOMMANDS: SUBCOMMANDS:
help Print this message or the help of the given subcommand(s)
more more
help Print this message or the help of the given subcommand(s)
""" """
stderr = "" stderr = ""

View file

@ -18,9 +18,9 @@ OPTIONS:
more log more log
SUBCOMMANDS: SUBCOMMANDS:
help
Print this message or the help of the given subcommand(s)
more more
help
Print this message or the help of the given subcommand(s)
""" """
stderr = "" stderr = ""

View file

@ -18,9 +18,9 @@ OPTIONS:
more log more log
SUBCOMMANDS: SUBCOMMANDS:
help
Print this message or the help of the given subcommand(s)
more more
help
Print this message or the help of the given subcommand(s)
""" """
stderr = "" stderr = ""