From f70ebe89a7e9d372f135137ee65da8c4de7bac56 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 8 Aug 2022 16:08:47 -0500 Subject: [PATCH] fix!: Require explicit help/version disabling Before we introduced actions, it required specific setups to engage with claps version and help printing. With actions making that more explicit, we don't get as much benefit from our multiple, obscure, ways of users customizing help Before - Modify existing help or version with `mut_arg` which would automatically be pushed down the command tree like `global(true)` - Create an new help or version and have it treated as if it was the built-in on (I think) - Use the same flags as built-in and have the built-in flags automatically disabled - Users could explicitly disable the built-in functionality and do what they want Now - `mut_arg` no longer works as we define help and version flags at the end - If someone defines a flag that overlaps with the built-ins by id, long, or short, a debug assert will tell them to explicitly disable the built-in - Any customization has to be done by a user providing their own. To propagate through the command tree, they need to set `global(true)`. Benefits - Hopefully, this makes it less confusing on how to override help behavior. Someone creates an arg and we then tell them how to disable the built-in - This greatly simplifies the arg handling by pushing more responsibility onto the developer in what are hopefully just corner cases - This removes about 1Kb from .text Fixes #3405 Fixes #4033 --- CHANGELOG.md | 5 + clap_bench/benches/05_ripgrep.rs | 2 + clap_complete/tests/common.rs | 2 +- clap_complete/tests/snapshots/aliases.bash | 2 +- clap_complete/tests/snapshots/aliases.elvish | 8 +- clap_complete/tests/snapshots/aliases.fish | 2 +- clap_complete/tests/snapshots/aliases.ps1 | 8 +- clap_complete/tests/snapshots/aliases.zsh | 8 +- clap_complete/tests/snapshots/basic.bash | 4 +- clap_complete/tests/snapshots/basic.elvish | 6 +- clap_complete/tests/snapshots/basic.fish | 4 +- clap_complete/tests/snapshots/basic.ps1 | 6 +- clap_complete/tests/snapshots/basic.zsh | 6 +- .../tests/snapshots/feature_sample.bash | 2 +- .../tests/snapshots/feature_sample.elvish | 8 +- .../tests/snapshots/feature_sample.fish | 2 +- .../tests/snapshots/feature_sample.ps1 | 8 +- .../tests/snapshots/feature_sample.zsh | 8 +- clap_complete/tests/snapshots/quoting.bash | 2 +- clap_complete/tests/snapshots/quoting.elvish | 8 +- clap_complete/tests/snapshots/quoting.fish | 4 +- clap_complete/tests/snapshots/quoting.ps1 | 8 +- clap_complete/tests/snapshots/quoting.zsh | 8 +- .../tests/snapshots/special_commands.bash | 2 +- .../tests/snapshots/special_commands.elvish | 8 +- .../tests/snapshots/special_commands.fish | 2 +- .../tests/snapshots/special_commands.ps1 | 8 +- .../tests/snapshots/special_commands.zsh | 8 +- .../tests/snapshots/sub_subcommands.bash | 2 +- .../tests/snapshots/sub_subcommands.elvish | 8 +- .../tests/snapshots/sub_subcommands.fish | 2 +- .../tests/snapshots/sub_subcommands.ps1 | 8 +- .../tests/snapshots/sub_subcommands.zsh | 8 +- clap_complete/tests/snapshots/value_hint.bash | 4 +- .../tests/snapshots/value_hint.elvish | 3 +- clap_complete/tests/snapshots/value_hint.fish | 4 +- clap_complete/tests/snapshots/value_hint.ps1 | 3 +- clap_complete/tests/snapshots/value_hint.zsh | 3 +- clap_complete_fig/tests/common.rs | 2 +- .../tests/snapshots/aliases.fig.js | 8 +- .../tests/snapshots/basic.fig.js | 14 +- .../tests/snapshots/feature_sample.fig.js | 10 +- .../tests/snapshots/quoting.fig.js | 16 +- .../tests/snapshots/special_commands.fig.js | 10 +- .../tests/snapshots/sub_subcommands.fig.js | 10 +- .../tests/snapshots/value_hint.fig.js | 4 +- clap_mangen/tests/common.rs | 2 +- clap_mangen/tests/snapshots/aliases.bash.roff | 14 +- clap_mangen/tests/snapshots/basic.bash.roff | 8 +- .../tests/snapshots/feature_sample.bash.roff | 8 +- .../tests/snapshots/hidden_option.bash.roff | 8 +- clap_mangen/tests/snapshots/quoting.bash.roff | 14 +- .../snapshots/special_commands.bash.roff | 8 +- .../tests/snapshots/sub_subcommands.bash.roff | 8 +- .../tests/snapshots/value_env.bash.roff | 8 +- .../tests/snapshots/value_hint.bash.roff | 10 +- src/builder/arg.rs | 20 -- src/builder/command.rs | 216 ++++-------------- src/builder/debug_asserts.rs | 54 +++-- src/mkeymap.rs | 5 - src/util/id.rs | 1 + tests/builder/app_settings.rs | 67 ------ tests/builder/derive_order.rs | 73 ------ tests/builder/flag_subcommands.rs | 4 + tests/builder/groups.rs | 8 +- tests/builder/help.rs | 162 ++++--------- tests/builder/hidden_args.rs | 18 +- tests/builder/version.rs | 97 ++------ 68 files changed, 348 insertions(+), 733 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4884293d026..ab3840d6bcd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Remove `Arg::use_value_delimiter` in favor of `Arg::value_delimiter` - Remove `Arg::require_value_delimiter`, either users could use `Arg::value_delimiter` or implement a custom parser with `TypedValueParser` - `ArgAction::SetTrue` and `ArgAction::SetFalse` now prioritize `Arg::default_missing_value` over their standard behavior +- `mut_arg` can no longer be used to customize help and version arguments, instead disable them (`Command::disable_help_flag`, `Command::disable_version_flag`) and provide your own +- `Arg::new("help")` and `Arg::new("version")` no longer implicitly disable the + built-in flags and be copied to all subcommands, instead disable + the built-in flags (`Command::disable_help_flag`, + `Command::disable_version_flag`) and mark the custom flags as `global(true)`. - *(help)* Make `DeriveDisplayOrder` the default and removed the setting. To sort help, set `next_display_order(None)` (#2808) - *(help)* Subcommand display order respects `Command::next_display_order` instead of `DeriveDisplayOrder` and using its own initial display order value (#2808) - *(env)* Parse `--help` and `--version` like any `ArgAction::SetTrue` flag (#3776) diff --git a/clap_bench/benches/05_ripgrep.rs b/clap_bench/benches/05_ripgrep.rs index 98d0b91810a..8cbe330a4f6 100644 --- a/clap_bench/benches/05_ripgrep.rs +++ b/clap_bench/benches/05_ripgrep.rs @@ -310,6 +310,8 @@ where .help_template(TEMPLATE) // Handle help/version manually to make their output formatting // consistent with short/long views. + .disable_help_flag(true) + .disable_version_flag(true) .arg(arg("help-short").short('h')) .arg(flag("help")) .arg(flag("version").short('V')) diff --git a/clap_complete/tests/common.rs b/clap_complete/tests/common.rs index f2512389a92..303f35b711b 100644 --- a/clap_complete/tests/common.rs +++ b/clap_complete/tests/common.rs @@ -231,7 +231,7 @@ pub fn value_hint_command(name: &'static str) -> clap::Command<'static> { ) .arg( clap::Arg::new("host") - .short('h') + .short('H') .long("host") .value_hint(clap::ValueHint::Hostname), ) diff --git a/clap_complete/tests/snapshots/aliases.bash b/clap_complete/tests/snapshots/aliases.bash index 913dec048d7..730e2f4350c 100644 --- a/clap_complete/tests/snapshots/aliases.bash +++ b/clap_complete/tests/snapshots/aliases.bash @@ -19,7 +19,7 @@ _my-app() { case "${cmd}" in my__app) - opts="-h -V -F -f -O -o --help --version --flg --flag --opt --option " + opts="-F -f -O -o -h -V --flg --flag --opt --option --help --version " if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/clap_complete/tests/snapshots/aliases.elvish b/clap_complete/tests/snapshots/aliases.elvish index 50853d0b7f2..eebe406d686 100644 --- a/clap_complete/tests/snapshots/aliases.elvish +++ b/clap_complete/tests/snapshots/aliases.elvish @@ -22,14 +22,14 @@ set edit:completion:arg-completer[my-app] = {|@words| cand -O 'cmd option' cand --option 'cmd option' cand --opt 'cmd option' - cand -h 'Print help information' - cand --help 'Print help information' - cand -V 'Print version information' - cand --version 'Print version information' cand -f 'cmd flag' cand -F 'cmd flag' cand --flag 'cmd flag' cand --flg 'cmd flag' + cand -h 'Print help information' + cand --help 'Print help information' + cand -V 'Print version information' + cand --version 'Print version information' } ] $completions[$command] diff --git a/clap_complete/tests/snapshots/aliases.fish b/clap_complete/tests/snapshots/aliases.fish index d6c774ae17a..9c0c219b59e 100644 --- a/clap_complete/tests/snapshots/aliases.fish +++ b/clap_complete/tests/snapshots/aliases.fish @@ -1,4 +1,4 @@ complete -c my-app -s o -s O -l option -l opt -d 'cmd option' -r +complete -c my-app -s f -s F -l flag -l flg -d 'cmd flag' complete -c my-app -s h -l help -d 'Print help information' complete -c my-app -s V -l version -d 'Print version information' -complete -c my-app -s f -s F -l flag -l flg -d 'cmd flag' diff --git a/clap_complete/tests/snapshots/aliases.ps1 b/clap_complete/tests/snapshots/aliases.ps1 index e0856f63107..76207207fc1 100644 --- a/clap_complete/tests/snapshots/aliases.ps1 +++ b/clap_complete/tests/snapshots/aliases.ps1 @@ -25,14 +25,14 @@ Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock { [CompletionResult]::new('-O', 'O', [CompletionResultType]::ParameterName, 'cmd option') [CompletionResult]::new('--option', 'option', [CompletionResultType]::ParameterName, 'cmd option') [CompletionResult]::new('--opt', 'opt', [CompletionResultType]::ParameterName, 'cmd option') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information') - [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information') - [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information') [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'cmd flag') [CompletionResult]::new('-F', 'F', [CompletionResultType]::ParameterName, 'cmd flag') [CompletionResult]::new('--flag', 'flag', [CompletionResultType]::ParameterName, 'cmd flag') [CompletionResult]::new('--flg', 'flg', [CompletionResultType]::ParameterName, 'cmd flag') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information') break } }) diff --git a/clap_complete/tests/snapshots/aliases.zsh b/clap_complete/tests/snapshots/aliases.zsh index 2168079668a..e3a063a7343 100644 --- a/clap_complete/tests/snapshots/aliases.zsh +++ b/clap_complete/tests/snapshots/aliases.zsh @@ -19,14 +19,14 @@ _my-app() { '*-O+[cmd option]: : ' / '*--option=[cmd option]: : ' / '*--opt=[cmd option]: : ' / -'*-h[Print help information]' / -'*--help[Print help information]' / -'*-V[Print version information]' / -'*--version[Print version information]' / '*-f[cmd flag]' / '*-F[cmd flag]' / '*--flag[cmd flag]' / '*--flg[cmd flag]' / +'*-h[Print help information]' / +'*--help[Print help information]' / +'*-V[Print version information]' / +'*--version[Print version information]' / '::positional:' / && ret=0 } diff --git a/clap_complete/tests/snapshots/basic.bash b/clap_complete/tests/snapshots/basic.bash index 0aa37b4cfd8..eabc9b504d0 100644 --- a/clap_complete/tests/snapshots/basic.bash +++ b/clap_complete/tests/snapshots/basic.bash @@ -25,7 +25,7 @@ _my-app() { case "${cmd}" in my__app) - opts="-h -c -v --help test help" + opts="-c -v -h --help test help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -53,7 +53,7 @@ _my-app() { return 0 ;; my__app__test) - opts="-d -h -c --help" + opts="-d -c -h --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/clap_complete/tests/snapshots/basic.elvish b/clap_complete/tests/snapshots/basic.elvish index 195c359612e..ca7c71fd263 100644 --- a/clap_complete/tests/snapshots/basic.elvish +++ b/clap_complete/tests/snapshots/basic.elvish @@ -18,18 +18,18 @@ set edit:completion:arg-completer[my-app] = {|@words| } var completions = [ &'my-app'= { - cand -h 'Print help information' - cand --help 'Print help information' cand -c 'c' cand -v 'v' + cand -h 'Print help information' + cand --help 'Print help information' cand test 'Subcommand' cand help 'Print this message or the help of the given subcommand(s)' } &'my-app;test'= { cand -d 'd' + cand -c 'c' cand -h 'Print help information' cand --help 'Print help information' - cand -c 'c' } &'my-app;help'= { cand -c 'c' diff --git a/clap_complete/tests/snapshots/basic.fish b/clap_complete/tests/snapshots/basic.fish index 5fdf2ce9f48..e836a340ef0 100644 --- a/clap_complete/tests/snapshots/basic.fish +++ b/clap_complete/tests/snapshots/basic.fish @@ -1,9 +1,9 @@ -complete -c my-app -n "__fish_use_subcommand" -s h -l help -d 'Print help information' complete -c my-app -n "__fish_use_subcommand" -s c complete -c my-app -n "__fish_use_subcommand" -s v +complete -c my-app -n "__fish_use_subcommand" -s h -l help -d 'Print help information' complete -c my-app -n "__fish_use_subcommand" -f -a "test" -d 'Subcommand' complete -c my-app -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' complete -c my-app -n "__fish_seen_subcommand_from test" -s d -complete -c my-app -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help information' complete -c my-app -n "__fish_seen_subcommand_from test" -s c +complete -c my-app -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help information' complete -c my-app -n "__fish_seen_subcommand_from help" -s c diff --git a/clap_complete/tests/snapshots/basic.ps1 b/clap_complete/tests/snapshots/basic.ps1 index 02985edfb97..96af4b570ab 100644 --- a/clap_complete/tests/snapshots/basic.ps1 +++ b/clap_complete/tests/snapshots/basic.ps1 @@ -21,19 +21,19 @@ Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock { $completions = @(switch ($command) { 'my-app' { - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information') [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'c') [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'v') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information') [CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'Subcommand') [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)') break } 'my-app;test' { [CompletionResult]::new('-d', 'd', [CompletionResultType]::ParameterName, 'd') + [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'c') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information') - [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'c') break } 'my-app;help' { diff --git a/clap_complete/tests/snapshots/basic.zsh b/clap_complete/tests/snapshots/basic.zsh index 3274279fae8..c72bc6dc397 100644 --- a/clap_complete/tests/snapshots/basic.zsh +++ b/clap_complete/tests/snapshots/basic.zsh @@ -15,10 +15,10 @@ _my-app() { local context curcontext="$curcontext" state line _arguments "${_arguments_options[@]}" / -'*-h[Print help information]' / -'*--help[Print help information]' / '*-c[]' / '(-c)*-v[]' / +'*-h[Print help information]' / +'*--help[Print help information]' / ":: :_my-app_commands" / "*::: :->my-app" / && ret=0 @@ -31,9 +31,9 @@ _my-app() { (test) _arguments "${_arguments_options[@]}" / '*-d[]' / +'*-c[]' / '*-h[Print help information]' / '*--help[Print help information]' / -'*-c[]' / && ret=0 ;; (help) diff --git a/clap_complete/tests/snapshots/feature_sample.bash b/clap_complete/tests/snapshots/feature_sample.bash index af529269b62..caebfbc56d0 100644 --- a/clap_complete/tests/snapshots/feature_sample.bash +++ b/clap_complete/tests/snapshots/feature_sample.bash @@ -25,7 +25,7 @@ _my-app() { case "${cmd}" in my__app) - opts="-h -V -C -c --help --version --conf --config first second test help" + opts="-C -c -h -V --conf --config --help --version first second test help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/clap_complete/tests/snapshots/feature_sample.elvish b/clap_complete/tests/snapshots/feature_sample.elvish index f4cae420262..bc18cbdc69b 100644 --- a/clap_complete/tests/snapshots/feature_sample.elvish +++ b/clap_complete/tests/snapshots/feature_sample.elvish @@ -18,14 +18,14 @@ set edit:completion:arg-completer[my-app] = {|@words| } var completions = [ &'my-app'= { - cand -h 'Print help information' - cand --help 'Print help information' - cand -V 'Print version information' - cand --version 'Print version information' cand -c 'some config file' cand -C 'some config file' cand --config 'some config file' cand --conf 'some config file' + cand -h 'Print help information' + cand --help 'Print help information' + cand -V 'Print version information' + cand --version 'Print version information' cand test 'tests things' cand help 'Print this message or the help of the given subcommand(s)' } diff --git a/clap_complete/tests/snapshots/feature_sample.fish b/clap_complete/tests/snapshots/feature_sample.fish index 7b5a0e0bc53..aa9666dfeb6 100644 --- a/clap_complete/tests/snapshots/feature_sample.fish +++ b/clap_complete/tests/snapshots/feature_sample.fish @@ -1,6 +1,6 @@ +complete -c my-app -n "__fish_use_subcommand" -s c -s C -l config -l conf -d 'some config file' complete -c my-app -n "__fish_use_subcommand" -s h -l help -d 'Print help information' complete -c my-app -n "__fish_use_subcommand" -s V -l version -d 'Print version information' -complete -c my-app -n "__fish_use_subcommand" -s c -s C -l config -l conf -d 'some config file' complete -c my-app -n "__fish_use_subcommand" -f -a "test" -d 'tests things' complete -c my-app -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' complete -c my-app -n "__fish_seen_subcommand_from test" -l case -d 'the case to test' -r diff --git a/clap_complete/tests/snapshots/feature_sample.ps1 b/clap_complete/tests/snapshots/feature_sample.ps1 index b47fd5b4eb1..bf1ec4d0f0e 100644 --- a/clap_complete/tests/snapshots/feature_sample.ps1 +++ b/clap_complete/tests/snapshots/feature_sample.ps1 @@ -21,14 +21,14 @@ Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock { $completions = @(switch ($command) { 'my-app' { - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information') - [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information') - [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information') [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'some config file') [CompletionResult]::new('-C', 'C', [CompletionResultType]::ParameterName, 'some config file') [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'some config file') [CompletionResult]::new('--conf', 'conf', [CompletionResultType]::ParameterName, 'some config file') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information') [CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'tests things') [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)') break diff --git a/clap_complete/tests/snapshots/feature_sample.zsh b/clap_complete/tests/snapshots/feature_sample.zsh index d745ce162fb..f8a675117ac 100644 --- a/clap_complete/tests/snapshots/feature_sample.zsh +++ b/clap_complete/tests/snapshots/feature_sample.zsh @@ -15,14 +15,14 @@ _my-app() { local context curcontext="$curcontext" state line _arguments "${_arguments_options[@]}" / -'*-h[Print help information]' / -'*--help[Print help information]' / -'*-V[Print version information]' / -'*--version[Print version information]' / '*-c[some config file]' / '*-C[some config file]' / '*--config[some config file]' / '*--conf[some config file]' / +'*-h[Print help information]' / +'*--help[Print help information]' / +'*-V[Print version information]' / +'*--version[Print version information]' / '::file -- some input file:_files' / '::choice:(first second)' / ":: :_my-app_commands" / diff --git a/clap_complete/tests/snapshots/quoting.bash b/clap_complete/tests/snapshots/quoting.bash index a4ae43a2009..80d0c14ed49 100644 --- a/clap_complete/tests/snapshots/quoting.bash +++ b/clap_complete/tests/snapshots/quoting.bash @@ -40,7 +40,7 @@ _my-app() { case "${cmd}" in my__app) - opts="-h -V --help --version --single-quotes --double-quotes --backticks --backslash --brackets --expansions cmd-single-quotes cmd-double-quotes cmd-backticks cmd-backslash cmd-brackets cmd-expansions help" + opts="-h -V --single-quotes --double-quotes --backticks --backslash --brackets --expansions --help --version cmd-single-quotes cmd-double-quotes cmd-backticks cmd-backslash cmd-brackets cmd-expansions help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/clap_complete/tests/snapshots/quoting.elvish b/clap_complete/tests/snapshots/quoting.elvish index 01242cec9ac..5c2c787be34 100644 --- a/clap_complete/tests/snapshots/quoting.elvish +++ b/clap_complete/tests/snapshots/quoting.elvish @@ -18,16 +18,16 @@ set edit:completion:arg-completer[my-app] = {|@words| } var completions = [ &'my-app'= { - cand -h 'Print help information' - cand --help 'Print help information' - cand -V 'Print version information' - cand --version 'Print version information' cand --single-quotes 'Can be ''always'', ''auto'', or ''never''' cand --double-quotes 'Can be "always", "auto", or "never"' cand --backticks 'For more information see `echo test`' cand --backslash 'Avoid ''/n''' cand --brackets 'List packages [filter]' cand --expansions 'Execute the shell command with $SHELL' + cand -h 'Print help information' + cand --help 'Print help information' + cand -V 'Print version information' + cand --version 'Print version information' cand cmd-single-quotes 'Can be ''always'', ''auto'', or ''never''' cand cmd-double-quotes 'Can be "always", "auto", or "never"' cand cmd-backticks 'For more information see `echo test`' diff --git a/clap_complete/tests/snapshots/quoting.fish b/clap_complete/tests/snapshots/quoting.fish index 139a0199981..c9e24fb7ae2 100644 --- a/clap_complete/tests/snapshots/quoting.fish +++ b/clap_complete/tests/snapshots/quoting.fish @@ -1,11 +1,11 @@ -complete -c my-app -n "__fish_use_subcommand" -s h -l help -d 'Print help information' -complete -c my-app -n "__fish_use_subcommand" -s V -l version -d 'Print version information' complete -c my-app -n "__fish_use_subcommand" -l single-quotes -d 'Can be /'always/', /'auto/', or /'never/'' complete -c my-app -n "__fish_use_subcommand" -l double-quotes -d 'Can be "always", "auto", or "never"' complete -c my-app -n "__fish_use_subcommand" -l backticks -d 'For more information see `echo test`' complete -c my-app -n "__fish_use_subcommand" -l backslash -d 'Avoid /'//n/'' complete -c my-app -n "__fish_use_subcommand" -l brackets -d 'List packages [filter]' complete -c my-app -n "__fish_use_subcommand" -l expansions -d 'Execute the shell command with $SHELL' +complete -c my-app -n "__fish_use_subcommand" -s h -l help -d 'Print help information' +complete -c my-app -n "__fish_use_subcommand" -s V -l version -d 'Print version information' complete -c my-app -n "__fish_use_subcommand" -f -a "cmd-single-quotes" -d 'Can be /'always/', /'auto/', or /'never/'' complete -c my-app -n "__fish_use_subcommand" -f -a "cmd-double-quotes" -d 'Can be "always", "auto", or "never"' complete -c my-app -n "__fish_use_subcommand" -f -a "cmd-backticks" -d 'For more information see `echo test`' diff --git a/clap_complete/tests/snapshots/quoting.ps1 b/clap_complete/tests/snapshots/quoting.ps1 index 9f4aec8aa93..78fa953f12f 100644 --- a/clap_complete/tests/snapshots/quoting.ps1 +++ b/clap_complete/tests/snapshots/quoting.ps1 @@ -21,16 +21,16 @@ Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock { $completions = @(switch ($command) { 'my-app' { - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information') - [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information') - [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information') [CompletionResult]::new('--single-quotes', 'single-quotes', [CompletionResultType]::ParameterName, 'Can be ''always'', ''auto'', or ''never''') [CompletionResult]::new('--double-quotes', 'double-quotes', [CompletionResultType]::ParameterName, 'Can be "always", "auto", or "never"') [CompletionResult]::new('--backticks', 'backticks', [CompletionResultType]::ParameterName, 'For more information see `echo test`') [CompletionResult]::new('--backslash', 'backslash', [CompletionResultType]::ParameterName, 'Avoid ''/n''') [CompletionResult]::new('--brackets', 'brackets', [CompletionResultType]::ParameterName, 'List packages [filter]') [CompletionResult]::new('--expansions', 'expansions', [CompletionResultType]::ParameterName, 'Execute the shell command with $SHELL') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information') [CompletionResult]::new('cmd-single-quotes', 'cmd-single-quotes', [CompletionResultType]::ParameterValue, 'Can be ''always'', ''auto'', or ''never''') [CompletionResult]::new('cmd-double-quotes', 'cmd-double-quotes', [CompletionResultType]::ParameterValue, 'Can be "always", "auto", or "never"') [CompletionResult]::new('cmd-backticks', 'cmd-backticks', [CompletionResultType]::ParameterValue, 'For more information see `echo test`') diff --git a/clap_complete/tests/snapshots/quoting.zsh b/clap_complete/tests/snapshots/quoting.zsh index 9953862c85d..e1b09fc981e 100644 --- a/clap_complete/tests/snapshots/quoting.zsh +++ b/clap_complete/tests/snapshots/quoting.zsh @@ -15,16 +15,16 @@ _my-app() { local context curcontext="$curcontext" state line _arguments "${_arguments_options[@]}" / -'*-h[Print help information]' / -'*--help[Print help information]' / -'*-V[Print version information]' / -'*--version[Print version information]' / '*--single-quotes[Can be '/''always'/'', '/''auto'/'', or '/''never'/'']' / '*--double-quotes[Can be "always", "auto", or "never"]' / '*--backticks[For more information see `echo test`]' / '*--backslash[Avoid '/''//n'/'']' / '*--brackets[List packages /[filter/]]' / '*--expansions[Execute the shell command with $SHELL]' / +'*-h[Print help information]' / +'*--help[Print help information]' / +'*-V[Print version information]' / +'*--version[Print version information]' / ":: :_my-app_commands" / "*::: :->my-app" / && ret=0 diff --git a/clap_complete/tests/snapshots/special_commands.bash b/clap_complete/tests/snapshots/special_commands.bash index bb603b5b11b..ef81e2b6329 100644 --- a/clap_complete/tests/snapshots/special_commands.bash +++ b/clap_complete/tests/snapshots/special_commands.bash @@ -34,7 +34,7 @@ _my-app() { case "${cmd}" in my__app) - opts="-h -V -C -c --help --version --conf --config first second test some_cmd some-cmd-with-hyphens some-hidden-cmd help" + opts="-C -c -h -V --conf --config --help --version first second test some_cmd some-cmd-with-hyphens some-hidden-cmd help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/clap_complete/tests/snapshots/special_commands.elvish b/clap_complete/tests/snapshots/special_commands.elvish index 26ba90d9d2f..fec8ac8767c 100644 --- a/clap_complete/tests/snapshots/special_commands.elvish +++ b/clap_complete/tests/snapshots/special_commands.elvish @@ -18,14 +18,14 @@ set edit:completion:arg-completer[my-app] = {|@words| } var completions = [ &'my-app'= { - cand -h 'Print help information' - cand --help 'Print help information' - cand -V 'Print version information' - cand --version 'Print version information' cand -c 'some config file' cand -C 'some config file' cand --config 'some config file' cand --conf 'some config file' + cand -h 'Print help information' + cand --help 'Print help information' + cand -V 'Print version information' + cand --version 'Print version information' cand test 'tests things' cand some_cmd 'tests other things' cand some-cmd-with-hyphens 'some-cmd-with-hyphens' diff --git a/clap_complete/tests/snapshots/special_commands.fish b/clap_complete/tests/snapshots/special_commands.fish index 22595889956..d0359632cda 100644 --- a/clap_complete/tests/snapshots/special_commands.fish +++ b/clap_complete/tests/snapshots/special_commands.fish @@ -1,6 +1,6 @@ +complete -c my-app -n "__fish_use_subcommand" -s c -s C -l config -l conf -d 'some config file' complete -c my-app -n "__fish_use_subcommand" -s h -l help -d 'Print help information' complete -c my-app -n "__fish_use_subcommand" -s V -l version -d 'Print version information' -complete -c my-app -n "__fish_use_subcommand" -s c -s C -l config -l conf -d 'some config file' complete -c my-app -n "__fish_use_subcommand" -f -a "test" -d 'tests things' complete -c my-app -n "__fish_use_subcommand" -f -a "some_cmd" -d 'tests other things' complete -c my-app -n "__fish_use_subcommand" -f -a "some-cmd-with-hyphens" diff --git a/clap_complete/tests/snapshots/special_commands.ps1 b/clap_complete/tests/snapshots/special_commands.ps1 index 246c9d1064e..924328985e8 100644 --- a/clap_complete/tests/snapshots/special_commands.ps1 +++ b/clap_complete/tests/snapshots/special_commands.ps1 @@ -21,14 +21,14 @@ Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock { $completions = @(switch ($command) { 'my-app' { - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information') - [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information') - [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information') [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'some config file') [CompletionResult]::new('-C', 'C', [CompletionResultType]::ParameterName, 'some config file') [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'some config file') [CompletionResult]::new('--conf', 'conf', [CompletionResultType]::ParameterName, 'some config file') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information') [CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'tests things') [CompletionResult]::new('some_cmd', 'some_cmd', [CompletionResultType]::ParameterValue, 'tests other things') [CompletionResult]::new('some-cmd-with-hyphens', 'some-cmd-with-hyphens', [CompletionResultType]::ParameterValue, 'some-cmd-with-hyphens') diff --git a/clap_complete/tests/snapshots/special_commands.zsh b/clap_complete/tests/snapshots/special_commands.zsh index 3785cd2845e..7e57caf368a 100644 --- a/clap_complete/tests/snapshots/special_commands.zsh +++ b/clap_complete/tests/snapshots/special_commands.zsh @@ -15,14 +15,14 @@ _my-app() { local context curcontext="$curcontext" state line _arguments "${_arguments_options[@]}" / -'*-h[Print help information]' / -'*--help[Print help information]' / -'*-V[Print version information]' / -'*--version[Print version information]' / '*-c[some config file]' / '*-C[some config file]' / '*--config[some config file]' / '*--conf[some config file]' / +'*-h[Print help information]' / +'*--help[Print help information]' / +'*-V[Print version information]' / +'*--version[Print version information]' / '::file -- some input file:_files' / '::choice:(first second)' / ":: :_my-app_commands" / diff --git a/clap_complete/tests/snapshots/sub_subcommands.bash b/clap_complete/tests/snapshots/sub_subcommands.bash index c96561de46d..be860b1da96 100644 --- a/clap_complete/tests/snapshots/sub_subcommands.bash +++ b/clap_complete/tests/snapshots/sub_subcommands.bash @@ -31,7 +31,7 @@ _my-app() { case "${cmd}" in my__app) - opts="-h -V -C -c --help --version --conf --config first second test some_cmd help" + opts="-C -c -h -V --conf --config --help --version first second test some_cmd help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/clap_complete/tests/snapshots/sub_subcommands.elvish b/clap_complete/tests/snapshots/sub_subcommands.elvish index da121c11c41..58ba8e7c6db 100644 --- a/clap_complete/tests/snapshots/sub_subcommands.elvish +++ b/clap_complete/tests/snapshots/sub_subcommands.elvish @@ -18,14 +18,14 @@ set edit:completion:arg-completer[my-app] = {|@words| } var completions = [ &'my-app'= { - cand -h 'Print help information' - cand --help 'Print help information' - cand -V 'Print version information' - cand --version 'Print version information' cand -c 'some config file' cand -C 'some config file' cand --config 'some config file' cand --conf 'some config file' + cand -h 'Print help information' + cand --help 'Print help information' + cand -V 'Print version information' + cand --version 'Print version information' cand test 'tests things' cand some_cmd 'top level subcommand' cand help 'Print this message or the help of the given subcommand(s)' diff --git a/clap_complete/tests/snapshots/sub_subcommands.fish b/clap_complete/tests/snapshots/sub_subcommands.fish index 8bdeb01958a..72805f911af 100644 --- a/clap_complete/tests/snapshots/sub_subcommands.fish +++ b/clap_complete/tests/snapshots/sub_subcommands.fish @@ -1,6 +1,6 @@ +complete -c my-app -n "__fish_use_subcommand" -s c -s C -l config -l conf -d 'some config file' complete -c my-app -n "__fish_use_subcommand" -s h -l help -d 'Print help information' complete -c my-app -n "__fish_use_subcommand" -s V -l version -d 'Print version information' -complete -c my-app -n "__fish_use_subcommand" -s c -s C -l config -l conf -d 'some config file' complete -c my-app -n "__fish_use_subcommand" -f -a "test" -d 'tests things' complete -c my-app -n "__fish_use_subcommand" -f -a "some_cmd" -d 'top level subcommand' complete -c my-app -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' diff --git a/clap_complete/tests/snapshots/sub_subcommands.ps1 b/clap_complete/tests/snapshots/sub_subcommands.ps1 index 2762ab5ce3c..fc0f051b7ff 100644 --- a/clap_complete/tests/snapshots/sub_subcommands.ps1 +++ b/clap_complete/tests/snapshots/sub_subcommands.ps1 @@ -21,14 +21,14 @@ Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock { $completions = @(switch ($command) { 'my-app' { - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information') - [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information') - [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information') [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'some config file') [CompletionResult]::new('-C', 'C', [CompletionResultType]::ParameterName, 'some config file') [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'some config file') [CompletionResult]::new('--conf', 'conf', [CompletionResultType]::ParameterName, 'some config file') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information') [CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'tests things') [CompletionResult]::new('some_cmd', 'some_cmd', [CompletionResultType]::ParameterValue, 'top level subcommand') [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)') diff --git a/clap_complete/tests/snapshots/sub_subcommands.zsh b/clap_complete/tests/snapshots/sub_subcommands.zsh index 78249b82ef6..c26b9ff9ec3 100644 --- a/clap_complete/tests/snapshots/sub_subcommands.zsh +++ b/clap_complete/tests/snapshots/sub_subcommands.zsh @@ -15,14 +15,14 @@ _my-app() { local context curcontext="$curcontext" state line _arguments "${_arguments_options[@]}" / -'*-h[Print help information]' / -'*--help[Print help information]' / -'*-V[Print version information]' / -'*--version[Print version information]' / '*-c[some config file]' / '*-C[some config file]' / '*--config[some config file]' / '*--conf[some config file]' / +'*-h[Print help information]' / +'*--help[Print help information]' / +'*-V[Print version information]' / +'*--version[Print version information]' / '::file -- some input file:_files' / '::choice:(first second)' / ":: :_my-app_commands" / diff --git a/clap_complete/tests/snapshots/value_hint.bash b/clap_complete/tests/snapshots/value_hint.bash index 39e8208b864..1e109c6b977 100644 --- a/clap_complete/tests/snapshots/value_hint.bash +++ b/clap_complete/tests/snapshots/value_hint.bash @@ -19,7 +19,7 @@ _my-app() { case "${cmd}" in my__app) - opts="-p -f -d -e -c -u -h --help --choice --unknown --other --path --file --dir --exe --cmd-name --cmd --user --host --url --email ..." + opts="-p -f -d -e -c -u -H -h --choice --unknown --other --path --file --dir --exe --cmd-name --cmd --user --host --url --email --help ..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -93,7 +93,7 @@ _my-app() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - -h) + -H) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; diff --git a/clap_complete/tests/snapshots/value_hint.elvish b/clap_complete/tests/snapshots/value_hint.elvish index 796647fe744..0cb62dc2fa0 100644 --- a/clap_complete/tests/snapshots/value_hint.elvish +++ b/clap_complete/tests/snapshots/value_hint.elvish @@ -34,10 +34,11 @@ set edit:completion:arg-completer[my-app] = {|@words| cand --cmd 'cmd' cand -u 'u' cand --user 'user' - cand -h 'h' + cand -H 'H' cand --host 'host' cand --url 'url' cand --email 'email' + cand -h 'Print help information' cand --help 'Print help information' } ] diff --git a/clap_complete/tests/snapshots/value_hint.fish b/clap_complete/tests/snapshots/value_hint.fish index e98b3bd52eb..d84c74350b4 100644 --- a/clap_complete/tests/snapshots/value_hint.fish +++ b/clap_complete/tests/snapshots/value_hint.fish @@ -8,7 +8,7 @@ complete -c my-app -s e -l exe -r -F complete -c my-app -l cmd-name -r -f -a "(__fish_complete_command)" complete -c my-app -s c -l cmd -r -f -a "(__fish_complete_command)" complete -c my-app -s u -l user -r -f -a "(__fish_complete_users)" -complete -c my-app -s h -l host -r -f -a "(__fish_print_hostnames)" +complete -c my-app -s H -l host -r -f -a "(__fish_print_hostnames)" complete -c my-app -l url -r -f complete -c my-app -l email -r -f -complete -c my-app -l help -d 'Print help information' +complete -c my-app -s h -l help -d 'Print help information' diff --git a/clap_complete/tests/snapshots/value_hint.ps1 b/clap_complete/tests/snapshots/value_hint.ps1 index 7389d268867..d64c03b3afb 100644 --- a/clap_complete/tests/snapshots/value_hint.ps1 +++ b/clap_complete/tests/snapshots/value_hint.ps1 @@ -37,10 +37,11 @@ Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock { [CompletionResult]::new('--cmd', 'cmd', [CompletionResultType]::ParameterName, 'cmd') [CompletionResult]::new('-u', 'u', [CompletionResultType]::ParameterName, 'u') [CompletionResult]::new('--user', 'user', [CompletionResultType]::ParameterName, 'user') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'h') + [CompletionResult]::new('-H', 'H', [CompletionResultType]::ParameterName, 'H') [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host') [CompletionResult]::new('--url', 'url', [CompletionResultType]::ParameterName, 'url') [CompletionResult]::new('--email', 'email', [CompletionResultType]::ParameterName, 'email') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information') break } diff --git a/clap_complete/tests/snapshots/value_hint.zsh b/clap_complete/tests/snapshots/value_hint.zsh index 068ff008aa7..59fb5cea650 100644 --- a/clap_complete/tests/snapshots/value_hint.zsh +++ b/clap_complete/tests/snapshots/value_hint.zsh @@ -31,10 +31,11 @@ _my-app() { '*--cmd=[]: :_cmdstring' / '*-u+[]: :_users' / '*--user=[]: :_users' / -'*-h+[]: :_hosts' / +'*-H+[]: :_hosts' / '*--host=[]: :_hosts' / '*--url=[]: :_urls' / '*--email=[]: :_email_addresses' / +'*-h[Print help information]' / '*--help[Print help information]' / '*::command_with_args:_cmdambivalent' / && ret=0 diff --git a/clap_complete_fig/tests/common.rs b/clap_complete_fig/tests/common.rs index f2512389a92..303f35b711b 100644 --- a/clap_complete_fig/tests/common.rs +++ b/clap_complete_fig/tests/common.rs @@ -231,7 +231,7 @@ pub fn value_hint_command(name: &'static str) -> clap::Command<'static> { ) .arg( clap::Arg::new("host") - .short('h') + .short('H') .long("host") .value_hint(clap::ValueHint::Hostname), ) diff --git a/clap_complete_fig/tests/snapshots/aliases.fig.js b/clap_complete_fig/tests/snapshots/aliases.fig.js index 8d5378b76a1..8cf108a4e45 100644 --- a/clap_complete_fig/tests/snapshots/aliases.fig.js +++ b/clap_complete_fig/tests/snapshots/aliases.fig.js @@ -11,6 +11,10 @@ const completion: Fig.Spec = { isOptional: true, }, }, + { + name: ["-f", "-F", "--flag", "--flg"], + description: "cmd flag", + }, { name: ["-h", "--help"], description: "Print help information", @@ -19,10 +23,6 @@ const completion: Fig.Spec = { name: ["-V", "--version"], description: "Print version information", }, - { - name: ["-f", "-F", "--flag", "--flg"], - description: "cmd flag", - }, ], args: { name: "positional", diff --git a/clap_complete_fig/tests/snapshots/basic.fig.js b/clap_complete_fig/tests/snapshots/basic.fig.js index 8502480d37e..ba7a90145fe 100644 --- a/clap_complete_fig/tests/snapshots/basic.fig.js +++ b/clap_complete_fig/tests/snapshots/basic.fig.js @@ -11,11 +11,11 @@ const completion: Fig.Spec = { isRepeatable: true, }, { - name: ["-h", "--help"], - description: "Print help information", + name: "-c", }, { - name: "-c", + name: ["-h", "--help"], + description: "Print help information", }, ], }, @@ -35,10 +35,6 @@ const completion: Fig.Spec = { }, ], options: [ - { - name: ["-h", "--help"], - description: "Print help information", - }, { name: "-c", }, @@ -48,6 +44,10 @@ const completion: Fig.Spec = { "-c", ], }, + { + name: ["-h", "--help"], + description: "Print help information", + }, ], }; diff --git a/clap_complete_fig/tests/snapshots/feature_sample.fig.js b/clap_complete_fig/tests/snapshots/feature_sample.fig.js index 07e48b5cb6e..f0799bc7c33 100644 --- a/clap_complete_fig/tests/snapshots/feature_sample.fig.js +++ b/clap_complete_fig/tests/snapshots/feature_sample.fig.js @@ -36,6 +36,11 @@ const completion: Fig.Spec = { }, ], options: [ + { + name: ["-c", "-C", "--config", "--conf"], + description: "some config file", + isRepeatable: true, + }, { name: ["-h", "--help"], description: "Print help information", @@ -44,11 +49,6 @@ const completion: Fig.Spec = { name: ["-V", "--version"], description: "Print version information", }, - { - name: ["-c", "-C", "--config", "--conf"], - description: "some config file", - isRepeatable: true, - }, ], args: [ { diff --git a/clap_complete_fig/tests/snapshots/quoting.fig.js b/clap_complete_fig/tests/snapshots/quoting.fig.js index c878edef3cf..0dc80bcad6a 100644 --- a/clap_complete_fig/tests/snapshots/quoting.fig.js +++ b/clap_complete_fig/tests/snapshots/quoting.fig.js @@ -73,14 +73,6 @@ const completion: Fig.Spec = { }, ], options: [ - { - name: ["-h", "--help"], - description: "Print help information", - }, - { - name: ["-V", "--version"], - description: "Print version information", - }, { name: "--single-quotes", description: "Can be 'always', 'auto', or 'never'", @@ -105,6 +97,14 @@ const completion: Fig.Spec = { name: "--expansions", description: "Execute the shell command with $SHELL", }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + { + name: ["-V", "--version"], + description: "Print version information", + }, ], }; diff --git a/clap_complete_fig/tests/snapshots/special_commands.fig.js b/clap_complete_fig/tests/snapshots/special_commands.fig.js index 632e2bf690b..ef1317c921e 100644 --- a/clap_complete_fig/tests/snapshots/special_commands.fig.js +++ b/clap_complete_fig/tests/snapshots/special_commands.fig.js @@ -93,6 +93,11 @@ const completion: Fig.Spec = { }, ], options: [ + { + name: ["-c", "-C", "--config", "--conf"], + description: "some config file", + isRepeatable: true, + }, { name: ["-h", "--help"], description: "Print help information", @@ -101,11 +106,6 @@ const completion: Fig.Spec = { name: ["-V", "--version"], description: "Print version information", }, - { - name: ["-c", "-C", "--config", "--conf"], - description: "some config file", - isRepeatable: true, - }, ], args: [ { diff --git a/clap_complete_fig/tests/snapshots/sub_subcommands.fig.js b/clap_complete_fig/tests/snapshots/sub_subcommands.fig.js index 8d17a992628..4e8293cc050 100644 --- a/clap_complete_fig/tests/snapshots/sub_subcommands.fig.js +++ b/clap_complete_fig/tests/snapshots/sub_subcommands.fig.js @@ -87,6 +87,11 @@ const completion: Fig.Spec = { }, ], options: [ + { + name: ["-c", "-C", "--config", "--conf"], + description: "some config file", + isRepeatable: true, + }, { name: ["-h", "--help"], description: "Print help information", @@ -95,11 +100,6 @@ const completion: Fig.Spec = { name: ["-V", "--version"], description: "Print version information", }, - { - name: ["-c", "-C", "--config", "--conf"], - description: "some config file", - isRepeatable: true, - }, ], args: [ { diff --git a/clap_complete_fig/tests/snapshots/value_hint.fig.js b/clap_complete_fig/tests/snapshots/value_hint.fig.js index 67fa2801be4..d6aec13250a 100644 --- a/clap_complete_fig/tests/snapshots/value_hint.fig.js +++ b/clap_complete_fig/tests/snapshots/value_hint.fig.js @@ -94,7 +94,7 @@ const completion: Fig.Spec = { }, }, { - name: ["-h", "--host"], + name: ["-H", "--host"], isRepeatable: true, args: { name: "host", @@ -118,7 +118,7 @@ const completion: Fig.Spec = { }, }, { - name: "--help", + name: ["-h", "--help"], description: "Print help information", }, ], diff --git a/clap_mangen/tests/common.rs b/clap_mangen/tests/common.rs index 242e3eadf84..13f20267eda 100644 --- a/clap_mangen/tests/common.rs +++ b/clap_mangen/tests/common.rs @@ -227,7 +227,7 @@ pub fn value_hint_command(name: &'static str) -> clap::Command<'static> { ) .arg( clap::Arg::new("host") - .short('h') + .short('H') .long("host") .value_hint(clap::ValueHint::Hostname), ) diff --git a/clap_mangen/tests/snapshots/aliases.bash.roff b/clap_mangen/tests/snapshots/aliases.bash.roff index 2f22d2234eb..959dfaa3edd 100644 --- a/clap_mangen/tests/snapshots/aliases.bash.roff +++ b/clap_mangen/tests/snapshots/aliases.bash.roff @@ -4,23 +4,23 @@ .SH NAME my/-app /- testing bash completions .SH SYNOPSIS -/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fB/-f/fR|/fB/-/-flag/fR] [/fB/-o/fR|/fB/-/-option/fR] [/fIpositional/fR] +/fBmy/-app/fR [/fB/-f/fR|/fB/-/-flag/fR] [/fB/-o/fR|/fB/-/-option/fR] [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fIpositional/fR] .SH DESCRIPTION testing bash completions .SH OPTIONS .TP -/fB/-h/fR, /fB/-/-help/fR -Print help information -.TP -/fB/-V/fR, /fB/-/-version/fR -Print version information -.TP /fB/-f/fR, /fB/-/-flag/fR [default: false] cmd flag .TP /fB/-o/fR, /fB/-/-option/fR cmd option .TP +/fB/-h/fR, /fB/-/-help/fR +Print help information +.TP +/fB/-V/fR, /fB/-/-version/fR +Print version information +.TP [/fIpositional/fR] .SH VERSION diff --git a/clap_mangen/tests/snapshots/basic.bash.roff b/clap_mangen/tests/snapshots/basic.bash.roff index 5655191eed8..b0e0f5b14ea 100644 --- a/clap_mangen/tests/snapshots/basic.bash.roff +++ b/clap_mangen/tests/snapshots/basic.bash.roff @@ -4,18 +4,18 @@ .SH NAME my/-app .SH SYNOPSIS -/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-c /fR] [/fB/-v /fR] [/fIsubcommands/fR] +/fBmy/-app/fR [/fB/-c /fR] [/fB/-v /fR] [/fB/-h/fR|/fB/-/-help/fR] [/fIsubcommands/fR] .SH DESCRIPTION .SH OPTIONS .TP -/fB/-h/fR, /fB/-/-help/fR -Print help information -.TP /fB/-c/fR [default: false] .TP /fB/-v/fR [default: false] +.TP +/fB/-h/fR, /fB/-/-help/fR +Print help information .SH SUBCOMMANDS .TP my/-app/-test(1) diff --git a/clap_mangen/tests/snapshots/feature_sample.bash.roff b/clap_mangen/tests/snapshots/feature_sample.bash.roff index 20fe84ee168..e6dc8818f0f 100644 --- a/clap_mangen/tests/snapshots/feature_sample.bash.roff +++ b/clap_mangen/tests/snapshots/feature_sample.bash.roff @@ -4,20 +4,20 @@ .SH NAME my/-app /- Tests completions .SH SYNOPSIS -/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fB/-c/fR|/fB/-/-config/fR] [/fIfile/fR] [/fIchoice/fR] [/fIsubcommands/fR] +/fBmy/-app/fR [/fB/-c/fR|/fB/-/-config/fR] [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fIfile/fR] [/fIchoice/fR] [/fIsubcommands/fR] .SH DESCRIPTION Tests completions .SH OPTIONS .TP +/fB/-c/fR, /fB/-/-config/fR [default: 0] +some config file +.TP /fB/-h/fR, /fB/-/-help/fR Print help information .TP /fB/-V/fR, /fB/-/-version/fR Print version information .TP -/fB/-c/fR, /fB/-/-config/fR [default: 0] -some config file -.TP [/fIfile/fR] some input file .TP diff --git a/clap_mangen/tests/snapshots/hidden_option.bash.roff b/clap_mangen/tests/snapshots/hidden_option.bash.roff index 1e9d119cc53..04227c2ef5f 100644 --- a/clap_mangen/tests/snapshots/hidden_option.bash.roff +++ b/clap_mangen/tests/snapshots/hidden_option.bash.roff @@ -4,12 +4,12 @@ .SH NAME my/-app .SH SYNOPSIS -/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-/-config/fR] +/fBmy/-app/fR [/fB/-/-config/fR] [/fB/-h/fR|/fB/-/-help/fR] .SH DESCRIPTION .SH OPTIONS .TP -/fB/-h/fR, /fB/-/-help/fR -Print help information -.TP /fB/-/-config/fR +.TP +/fB/-h/fR, /fB/-/-help/fR +Print help information diff --git a/clap_mangen/tests/snapshots/quoting.bash.roff b/clap_mangen/tests/snapshots/quoting.bash.roff index f0e0e1b5b09..7ca1e33241f 100644 --- a/clap_mangen/tests/snapshots/quoting.bash.roff +++ b/clap_mangen/tests/snapshots/quoting.bash.roff @@ -4,16 +4,10 @@ .SH NAME my/-app .SH SYNOPSIS -/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fB/-/-single/-quotes/fR] [/fB/-/-double/-quotes/fR] [/fB/-/-backticks/fR] [/fB/-/-backslash/fR] [/fB/-/-brackets/fR] [/fB/-/-expansions/fR] [/fIsubcommands/fR] +/fBmy/-app/fR [/fB/-/-single/-quotes/fR] [/fB/-/-double/-quotes/fR] [/fB/-/-backticks/fR] [/fB/-/-backslash/fR] [/fB/-/-brackets/fR] [/fB/-/-expansions/fR] [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fIsubcommands/fR] .SH DESCRIPTION .SH OPTIONS .TP -/fB/-h/fR, /fB/-/-help/fR -Print help information -.TP -/fB/-V/fR, /fB/-/-version/fR -Print version information -.TP /fB/-/-single/-quotes/fR [default: false] Can be /*(Aqalways/*(Aq, /*(Aqauto/*(Aq, or /*(Aqnever/*(Aq .TP @@ -31,6 +25,12 @@ List packages [filter] .TP /fB/-/-expansions/fR [default: false] Execute the shell command with $SHELL +.TP +/fB/-h/fR, /fB/-/-help/fR +Print help information +.TP +/fB/-V/fR, /fB/-/-version/fR +Print version information .SH SUBCOMMANDS .TP my/-app/-cmd/-single/-quotes(1) diff --git a/clap_mangen/tests/snapshots/special_commands.bash.roff b/clap_mangen/tests/snapshots/special_commands.bash.roff index cde4467aa74..f5b2f0593a3 100644 --- a/clap_mangen/tests/snapshots/special_commands.bash.roff +++ b/clap_mangen/tests/snapshots/special_commands.bash.roff @@ -4,20 +4,20 @@ .SH NAME my/-app /- Tests completions .SH SYNOPSIS -/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fB/-c/fR|/fB/-/-config/fR] [/fIfile/fR] [/fIchoice/fR] [/fIsubcommands/fR] +/fBmy/-app/fR [/fB/-c/fR|/fB/-/-config/fR] [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fIfile/fR] [/fIchoice/fR] [/fIsubcommands/fR] .SH DESCRIPTION Tests completions .SH OPTIONS .TP +/fB/-c/fR, /fB/-/-config/fR [default: 0] +some config file +.TP /fB/-h/fR, /fB/-/-help/fR Print help information .TP /fB/-V/fR, /fB/-/-version/fR Print version information .TP -/fB/-c/fR, /fB/-/-config/fR [default: 0] -some config file -.TP [/fIfile/fR] some input file .TP diff --git a/clap_mangen/tests/snapshots/sub_subcommands.bash.roff b/clap_mangen/tests/snapshots/sub_subcommands.bash.roff index 0e8823864a6..a1a713aa278 100644 --- a/clap_mangen/tests/snapshots/sub_subcommands.bash.roff +++ b/clap_mangen/tests/snapshots/sub_subcommands.bash.roff @@ -4,20 +4,20 @@ .SH NAME my/-app /- Tests completions .SH SYNOPSIS -/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fB/-c/fR|/fB/-/-config/fR] [/fIfile/fR] [/fIchoice/fR] [/fIsubcommands/fR] +/fBmy/-app/fR [/fB/-c/fR|/fB/-/-config/fR] [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fIfile/fR] [/fIchoice/fR] [/fIsubcommands/fR] .SH DESCRIPTION Tests completions .SH OPTIONS .TP +/fB/-c/fR, /fB/-/-config/fR [default: 0] +some config file +.TP /fB/-h/fR, /fB/-/-help/fR Print help information .TP /fB/-V/fR, /fB/-/-version/fR Print version information .TP -/fB/-c/fR, /fB/-/-config/fR [default: 0] -some config file -.TP [/fIfile/fR] some input file .TP diff --git a/clap_mangen/tests/snapshots/value_env.bash.roff b/clap_mangen/tests/snapshots/value_env.bash.roff index 4bed69f98c6..a6ef6dddb13 100644 --- a/clap_mangen/tests/snapshots/value_env.bash.roff +++ b/clap_mangen/tests/snapshots/value_env.bash.roff @@ -4,15 +4,15 @@ .SH NAME my/-app .SH SYNOPSIS -/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-c /fR] +/fBmy/-app/fR [/fB/-c /fR] [/fB/-h/fR|/fB/-/-help/fR] .SH DESCRIPTION .SH OPTIONS .TP -/fB/-h/fR, /fB/-/-help/fR -Print help information -.TP /fB/-c/fR [default: config.toml] Set configuration file path .RS May also be specified with the /fBCONFIG_FILE/fR environment variable. .RE +.TP +/fB/-h/fR, /fB/-/-help/fR +Print help information diff --git a/clap_mangen/tests/snapshots/value_hint.bash.roff b/clap_mangen/tests/snapshots/value_hint.bash.roff index cb02d3ca96f..bfcd4970102 100644 --- a/clap_mangen/tests/snapshots/value_hint.bash.roff +++ b/clap_mangen/tests/snapshots/value_hint.bash.roff @@ -4,13 +4,10 @@ .SH NAME my/-app .SH SYNOPSIS -/fBmy/-app/fR [/fB/-/-help/fR] [/fB/-/-choice/fR] [/fB/-/-unknown/fR] [/fB/-/-other/fR] [/fB/-p/fR|/fB/-/-path/fR] [/fB/-f/fR|/fB/-/-file/fR] [/fB/-d/fR|/fB/-/-dir/fR] [/fB/-e/fR|/fB/-/-exe/fR] [/fB/-/-cmd/-name/fR] [/fB/-c/fR|/fB/-/-cmd/fR] [/fB/-u/fR|/fB/-/-user/fR] [/fB/-h/fR|/fB/-/-host/fR] [/fB/-/-url/fR] [/fB/-/-email/fR] [/fIcommand_with_args/fR] +/fBmy/-app/fR [/fB/-/-choice/fR] [/fB/-/-unknown/fR] [/fB/-/-other/fR] [/fB/-p/fR|/fB/-/-path/fR] [/fB/-f/fR|/fB/-/-file/fR] [/fB/-d/fR|/fB/-/-dir/fR] [/fB/-e/fR|/fB/-/-exe/fR] [/fB/-/-cmd/-name/fR] [/fB/-c/fR|/fB/-/-cmd/fR] [/fB/-u/fR|/fB/-/-user/fR] [/fB/-H/fR|/fB/-/-host/fR] [/fB/-/-url/fR] [/fB/-/-email/fR] [/fB/-h/fR|/fB/-/-help/fR] [/fIcommand_with_args/fR] .SH DESCRIPTION .SH OPTIONS .TP -/fB/-/-help/fR -Print help information -.TP /fB/-/-choice/fR .TP @@ -41,7 +38,7 @@ Print help information /fB/-u/fR, /fB/-/-user/fR .TP -/fB/-h/fR, /fB/-/-host/fR +/fB/-H/fR, /fB/-/-host/fR .TP /fB/-/-url/fR @@ -49,6 +46,9 @@ Print help information .TP /fB/-/-email/fR +.TP +/fB/-h/fR, /fB/-/-help/fR +Print help information .TP [/fIcommand_with_args/fR] diff --git a/src/builder/arg.rs b/src/builder/arg.rs index fe008f1ac75..22e04285f63 100644 --- a/src/builder/arg.rs +++ b/src/builder/arg.rs @@ -50,7 +50,6 @@ use crate::INTERNAL_ERROR_MSG; #[derive(Default, Clone)] pub struct Arg<'help> { pub(crate) id: Id, - pub(crate) provider: ArgProvider, pub(crate) name: &'help str, pub(crate) help: Option<&'help str>, pub(crate) long_help: Option<&'help str>, @@ -3958,11 +3957,6 @@ impl<'help> Arg<'help> { } } - pub(crate) fn generated(mut self) -> Self { - self.provider = ArgProvider::Generated; - self - } - pub(crate) fn longest_filter(&self) -> bool { self.is_takes_value_set() || self.long.is_some() || self.short.is_none() } @@ -4092,7 +4086,6 @@ impl<'help> fmt::Debug for Arg<'help> { #[allow(unused_mut)] let mut ds = ds .field("id", &self.id) - .field("provider", &self.provider) .field("name", &self.name) .field("help", &self.help) .field("long_help", &self.long_help) @@ -4130,19 +4123,6 @@ impl<'help> fmt::Debug for Arg<'help> { } } -#[derive(Debug, Clone, Eq, PartialEq)] -pub(crate) enum ArgProvider { - Generated, - GeneratedMutated, - User, -} - -impl Default for ArgProvider { - fn default() -> Self { - ArgProvider::User - } -} - /// Write the values such as pub(crate) fn render_arg_val(arg: &Arg) -> String { let mut rendered = String::new(); diff --git a/src/builder/command.rs b/src/builder/command.rs index b864a3eff0a..f3d70c7a0da 100644 --- a/src/builder/command.rs +++ b/src/builder/command.rs @@ -12,7 +12,7 @@ use crate::builder::app_settings::{AppFlags, AppSettings}; use crate::builder::arg_settings::ArgSettings; use crate::builder::ArgAction; use crate::builder::PossibleValue; -use crate::builder::{arg::ArgProvider, Arg, ArgGroup, ArgPredicate}; +use crate::builder::{Arg, ArgGroup, ArgPredicate}; use crate::error::ErrorKind; use crate::error::Result as ClapResult; use crate::mkeymap::MKeyMap; @@ -130,22 +130,6 @@ impl<'help> Command<'help> { name, ..Default::default() } - .arg( - Arg::new("help") - .long("help") - .action(ArgAction::Help) - .help("Print help information") - .global(true) - .generated(), - ) - .arg( - Arg::new("version") - .long("version") - .action(ArgAction::Version) - .help("Print version information") - .global(true) - .generated(), - ) } new_inner(name.into()) @@ -173,14 +157,15 @@ impl<'help> Command<'help> { /// ``` /// [argument]: Arg #[must_use] - pub fn arg>>(self, a: A) -> Self { + pub fn arg>>(mut self, a: A) -> Self { let arg = a.into(); - self.arg_internal(arg) + self.arg_internal(arg); + self } - fn arg_internal(mut self, mut arg: Arg<'help>) -> Self { + fn arg_internal(&mut self, mut arg: Arg<'help>) { if let Some(current_disp_ord) = self.current_disp_ord.as_mut() { - if !arg.is_positional() && arg.provider != ArgProvider::Generated { + if !arg.is_positional() { let current = *current_disp_ord; arg.disp_ord.get_or_insert(current); *current_disp_ord = current + 1; @@ -189,7 +174,6 @@ impl<'help> Command<'help> { arg.help_heading.get_or_insert(self.current_help_heading); self.args.push(arg); - self } /// Adds multiple [arguments] to the list of valid possibilities. @@ -256,16 +240,12 @@ impl<'help> Command<'help> { let arg_id: &str = arg_id.into(); let id = Id::from(arg_id); - let mut a = self.args.remove_by_name(&id).unwrap_or_else(|| Arg { + let a = self.args.remove_by_name(&id).unwrap_or_else(|| Arg { id, name: arg_id, ..Arg::default() }); - if a.provider == ArgProvider::Generated { - a.provider = ArgProvider::GeneratedMutated; - } - self.args.push(f(a)); self } @@ -3536,6 +3516,7 @@ impl<'help> Command<'help> { /// Report whether [`Command::disable_version_flag`] is set pub fn is_disable_version_flag_set(&self) -> bool { self.is_set(AppSettings::DisableVersionFlag) + || (self.version.is_none() && self.long_version.is_none()) } /// Report whether [`Command::propagate_version`] is set @@ -3778,6 +3759,10 @@ impl<'help> Command<'help> { self.settings .insert(AppSettings::AllowExternalSubcommands.into()); } + if !self.has_subcommands() { + self.settings + .insert(AppSettings::DisableHelpSubcommand.into()); + } self._propagate(); self._check_help_and_version(); @@ -4060,40 +4045,21 @@ impl<'help> Command<'help> { for sc in &mut self.subcommands { for a in self.args.args().filter(|a| a.is_global_set()) { - let mut propagate = false; - let is_generated = matches!( - a.provider, - ArgProvider::Generated | ArgProvider::GeneratedMutated - ); - - // Remove generated help and version args in the subcommand - // - // Don't remove if those args are further mutated - if is_generated { - let generated_pos = sc - .args - .args() - .position(|x| x.id == a.id && x.provider == ArgProvider::Generated); - - if let Some(index) = generated_pos { - debug!( - "Command::_propagate removing {}'s {:?}", - sc.get_name(), - a.id - ); - sc.args.remove(index); - propagate = true; - } - } - - if propagate || sc.find(&a.id).is_none() { + if sc.find(&a.id).is_some() { debug!( - "Command::_propagate pushing {:?} to {}", + "Command::_propagate skipping {:?} to {}, already exists", a.id, sc.get_name(), ); - sc.args.push(a.clone()); + continue; } + + debug!( + "Command::_propagate pushing {:?} to {}", + a.id, + sc.get_name(), + ); + sc.args.push(a.clone()); } } } @@ -4128,129 +4094,38 @@ impl<'help> Command<'help> { } } - #[allow(clippy::blocks_in_if_conditions)] pub(crate) fn _check_help_and_version(&mut self) { - debug!("Command::_check_help_and_version: {}", self.name); - - if self.is_set(AppSettings::DisableHelpFlag) - || self.args.args().any(|x| { - x.provider == ArgProvider::User - && (x.long == Some("help") || x.id == Id::help_hash()) - }) - || self - .subcommands - .iter() - .any(|sc| sc.long_flag == Some("help")) - { - let generated_help_pos = self - .args - .args() - .position(|x| x.id == Id::help_hash() && x.provider == ArgProvider::Generated); - - if let Some(index) = generated_help_pos { - debug!("Command::_check_help_and_version: Removing generated help"); - self.args.remove(index); - } - } else { - let help = self - .args - .args() - .find(|x| x.id == Id::help_hash()) - .expect(INTERNAL_ERROR_MSG); - assert_ne!(help.provider, ArgProvider::User); - - if help.short.is_some() { - if help.short == Some('h') { - if let Some(other_arg) = self - .args - .args() - .find(|x| x.id != Id::help_hash() && x.short == Some('h')) - { - panic!( - "`help`s `-h` conflicts with `{}`. - -To change `help`s short, call `cmd.arg(Arg::new(\"help\")...)`.", - other_arg.name - ); - } - } - } else if !(self.args.args().any(|x| x.short == Some('h')) - || self.subcommands.iter().any(|sc| sc.short_flag == Some('h'))) - { - let help = self - .args - .args_mut() - .find(|x| x.id == Id::help_hash()) - .expect(INTERNAL_ERROR_MSG); - help.short = Some('h'); - } else { - debug!("Command::_check_help_and_version: Removing `-h` from help"); - } + debug!("Command::_check_help_and_version:{}", self.name,); + + if !self.is_disable_help_flag_set() { + debug!("Command::_check_help_and_version: Building default --help"); + let arg = Arg::new("help") + .short('h') + .long("help") + .action(ArgAction::Help) + .help("Print help information"); + // Avoiding `arg_internal` to not be sensitive to `next_help_heading` / + // `next_display_order` + self.args.push(arg); } - - // Determine if we should remove the generated --version flag - // - // Note that if only mut_arg() was used, the first expression will evaluate to `true` - // however inside the condition block, we only check for Generated args, not - // GeneratedMutated args, so the `mut_arg("version", ..) will be skipped and fall through - // to the following condition below (Adding the short `-V`) - if self.settings.is_set(AppSettings::DisableVersionFlag) - || (self.version.is_none() && self.long_version.is_none()) - || self.args.args().any(|x| { - x.provider == ArgProvider::User - && (x.long == Some("version") || x.id == Id::version_hash()) - }) - || self - .subcommands - .iter() - .any(|sc| sc.long_flag == Some("version")) - { - // This is the check mentioned above that only checks for Generated, not - // GeneratedMutated args by design. - let generated_version_pos = self - .args - .args() - .position(|x| x.id == Id::version_hash() && x.provider == ArgProvider::Generated); - - if let Some(index) = generated_version_pos { - debug!("Command::_check_help_and_version: Removing generated version"); - self.args.remove(index); - } + if !self.is_disable_version_flag_set() { + debug!("Command::_check_help_and_version: Building default --version"); + let arg = Arg::new("version") + .short('V') + .long("version") + .action(ArgAction::Version) + .help("Print version information"); + // Avoiding `arg_internal` to not be sensitive to `next_help_heading` / + // `next_display_order` + self.args.push(arg); } - // If we still have a generated --version flag, determine if we can apply the short `-V` - if self.args.args().any(|x| { - x.id == Id::version_hash() - && matches!( - x.provider, - ArgProvider::Generated | ArgProvider::GeneratedMutated - ) - }) { - let other_arg_has_short = self.args.args().any(|x| x.short == Some('V')); - let version = self - .args - .args_mut() - .find(|x| x.id == Id::version_hash()) - .expect(INTERNAL_ERROR_MSG); - - if !(version.short.is_some() - || other_arg_has_short - || self.subcommands.iter().any(|sc| sc.short_flag == Some('V'))) - { - version.short = Some('V'); - } - } - - if !self.is_set(AppSettings::DisableHelpSubcommand) - && self.has_subcommands() - && !self.subcommands.iter().any(|s| s.id == Id::help_hash()) - { + if !self.is_set(AppSettings::DisableHelpSubcommand) { debug!("Command::_check_help_and_version: Building help subcommand"); let mut help_subcmd = Command::new("help") .about("Print this message or the help of the given subcommand(s)") .arg( Arg::new("subcommand") - .index(1) .action(ArgAction::Append) .num_args(..) .value_name("SUBCOMMAND") @@ -4264,6 +4139,7 @@ To change `help`s short, call `cmd.arg(Arg::new(\"help\")...)`.", help_subcmd.long_version = None; help_subcmd = help_subcmd .setting(AppSettings::DisableHelpFlag) + .setting(AppSettings::DisableVersionFlag) .unset_global_setting(AppSettings::PropagateVersion); self.subcommands.push(help_subcmd); diff --git a/src/builder/debug_asserts.rs b/src/builder/debug_asserts.rs index 8e80594e29e..520d206f35b 100644 --- a/src/builder/debug_asserts.rs +++ b/src/builder/debug_asserts.rs @@ -2,9 +2,9 @@ use std::cmp::Ordering; use clap_lex::RawOsStr; -use crate::builder::arg::ArgProvider; use crate::builder::ValueRange; use crate::mkeymap::KeyType; +use crate::util::Id; use crate::ArgAction; use crate::INTERNAL_ERROR_MSG; use crate::{Arg, Command, ValueHint}; @@ -27,14 +27,7 @@ pub(crate) fn assert_app(cmd: &Command) { // Used `Command::mut_arg("version", ..) but did not provide any version information to display let version_needed = cmd .get_arguments() - .filter(|x| { - let action_set = matches!(x.get_action(), ArgAction::Version); - let provider_set = matches!( - x.provider, - ArgProvider::User | ArgProvider::GeneratedMutated - ); - action_set && provider_set - }) + .filter(|x| matches!(x.get_action(), ArgAction::Version)) .map(|x| x.get_id()) .collect::>(); @@ -90,23 +83,26 @@ pub(crate) fn assert_app(cmd: &Command) { } // Name conflicts - assert!( - cmd.two_args_of(|x| x.id == arg.id).is_none(), - "Command {}: Argument names must be unique, but '{}' is in use by more than one argument or group", + if let Some((first, second)) = cmd.two_args_of(|x| x.id == arg.id) { + panic!( + "Command {}: Argument names must be unique, but '{}' is in use by more than one argument or group{}", cmd.get_name(), arg.name, + duplicate_tip(cmd, first, second), ); + } // Long conflicts if let Some(l) = arg.long { if let Some((first, second)) = cmd.two_args_of(|x| x.long == Some(l)) { panic!( "Command {}: Long option names must be unique for each argument, \ - but '--{}' is in use by both '{}' and '{}'", + but '--{}' is in use by both '{}' and '{}'{}", cmd.get_name(), l, first.name, - second.name + second.name, + duplicate_tip(cmd, first, second) ) } } @@ -116,11 +112,12 @@ pub(crate) fn assert_app(cmd: &Command) { if let Some((first, second)) = cmd.two_args_of(|x| x.short == Some(s)) { panic!( "Command {}: Short option names must be unique for each argument, \ - but '-{}' is in use by both '{}' and '{}'", + but '-{}' is in use by both '{}' and '{}'{}", cmd.get_name(), s, first.name, - second.name + second.name, + duplicate_tip(cmd, first, second), ) } } @@ -351,6 +348,20 @@ pub(crate) fn assert_app(cmd: &Command) { assert_app_flags(cmd); } +fn duplicate_tip(cmd: &Command<'_>, first: &Arg<'_>, second: &Arg<'_>) -> &'static str { + if !cmd.is_disable_help_flag_set() + && (first.id == Id::help_hash() || second.id == Id::help_hash()) + { + " (call `cmd.disable_help_flag(true)` to remove the auto-generated `--help`)" + } else if !cmd.is_disable_version_flag_set() + && (first.id == Id::version_hash() || second.id == Id::version_hash()) + { + " (call `cmd.disable_version_flag(true)` to remove the auto-generated `--version`)" + } else { + "" + } +} + #[derive(Eq)] enum Flag<'a> { Command(String, &'a str), @@ -689,8 +700,15 @@ fn assert_arg(arg: &Arg) { ); assert!( arg.is_takes_value_set(), - "Argument '{}` is positional, it must take a value", - arg.name + "Argument '{}` is positional, it must take a value{}", + arg.name, + if arg.id == Id::help_hash() { + " (`mut_arg` no longer works with implicit `--help`)" + } else if arg.id == Id::help_hash() || arg.id == Id::version_hash() { + " (`mut_arg` no longer works with implicit `--version`)" + } else { + "" + } ); } diff --git a/src/mkeymap.rs b/src/mkeymap.rs index 97ecdda7766..56f22b6977f 100644 --- a/src/mkeymap.rs +++ b/src/mkeymap.rs @@ -151,11 +151,6 @@ impl<'help> MKeyMap<'help> { // since it's a cold function, using this wouldn't hurt much .map(|i| self.args.remove(i)) } - - /// Remove an arg based on index - pub(crate) fn remove(&mut self, index: usize) -> Arg<'help> { - self.args.remove(index) - } } impl<'help> Index<&'_ KeyType> for MKeyMap<'help> { diff --git a/src/util/id.rs b/src/util/id.rs index 63a7e003ee9..29dfe5a616e 100644 --- a/src/util/id.rs +++ b/src/util/id.rs @@ -18,6 +18,7 @@ macro_rules! precomputed_hashes { ($($fn_name:ident, $const:expr, $name:expr;)*) => { impl Id { $( + #[allow(dead_code)] pub(crate) fn $fn_name() -> Self { Id { #[cfg(debug_assertions)] diff --git a/tests/builder/app_settings.rs b/tests/builder/app_settings.rs index 799607f7c83..abc43194a95 100644 --- a/tests/builder/app_settings.rs +++ b/tests/builder/app_settings.rs @@ -1231,73 +1231,6 @@ fn aaos_option_use_delim_false() { ); } -#[test] -fn no_auto_help() { - let cmd = Command::new("myprog") - .subcommand(Command::new("foo")) - .mut_arg("help", |v| v.action(ArgAction::SetTrue)); - - let result = cmd.clone().try_get_matches_from("myprog --help".split(' ')); - assert!(result.is_ok(), "{}", result.unwrap_err()); - assert_eq!(result.unwrap().get_one::("help").copied(), Some(true)); - - let result = cmd.clone().try_get_matches_from("myprog -h".split(' ')); - assert!(result.is_ok(), "{}", result.unwrap_err()); - assert_eq!(result.unwrap().get_one::("help").copied(), Some(true)); -} - -#[test] -fn no_auto_version() { - let cmd = Command::new("myprog") - .version("3.0") - .mut_arg("version", |v| v.action(ArgAction::SetTrue)); - - let result = cmd - .clone() - .try_get_matches_from("myprog --version".split(' ')); - - assert!(result.is_ok(), "{}", result.unwrap_err()); - assert_eq!( - result.unwrap().get_one::("version").copied(), - Some(true) - ); - - let result = cmd.clone().try_get_matches_from("myprog -V".split(' ')); - - assert!(result.is_ok(), "{}", result.unwrap_err()); - assert_eq!( - result.unwrap().get_one::("version").copied(), - Some(true) - ); -} - -#[test] -fn no_auto_version_mut_arg() { - let cmd = Command::new("myprog") - .version("3.0") - .mut_arg("version", |v| { - v.action(ArgAction::SetTrue).help("custom help") - }); - - let result = cmd - .clone() - .try_get_matches_from("myprog --version".split(' ')); - - assert!(result.is_ok(), "{}", result.unwrap_err()); - assert_eq!( - result.unwrap().get_one::("version").copied(), - Some(true) - ); - - let result = cmd.clone().try_get_matches_from("myprog -V".split(' ')); - - assert!(result.is_ok(), "{}", result.unwrap_err()); - assert_eq!( - result.unwrap().get_one::("version").copied(), - Some(true) - ); -} - #[test] #[cfg(feature = "color")] fn color_is_global() { diff --git a/tests/builder/derive_order.rs b/tests/builder/derive_order.rs index 45ee9499990..480cd00c90c 100644 --- a/tests/builder/derive_order.rs +++ b/tests/builder/derive_order.rs @@ -264,79 +264,6 @@ OPTIONS: ); } -#[test] -fn prefer_user_help_with_derive_order() { - static PREFER_USER_HELP_DERIVE_ORDER: &str = "test 1.2 - -USAGE: - test [OPTIONS] - -OPTIONS: - -h, --help Print help message - --flag_b first flag - --flag_a second flag - -V, --version Print version information -"; - - let cmd = Command::new("test").version("1.2").args(&[ - Arg::new("help") - .long("help") - .short('h') - .help("Print help message") - .action(ArgAction::Help), - Arg::new("flag_b") - .long("flag_b") - .help("first flag") - .action(ArgAction::SetTrue), - Arg::new("flag_a") - .long("flag_a") - .help("second flag") - .action(ArgAction::SetTrue), - ]); - - utils::assert_output(cmd, "test --help", PREFER_USER_HELP_DERIVE_ORDER, false); -} - -#[test] -fn prefer_user_help_in_subcommand_with_derive_order() { - static PREFER_USER_HELP_SUBCMD_DERIVE_ORDER: &str = "test-sub 1.2 - -USAGE: - test sub [OPTIONS] - -OPTIONS: - -h, --help Print help message - --flag_b first flag - --flag_a second flag - -V, --version Print version information -"; - - let cmd = Command::new("test").subcommand( - Command::new("sub").version("1.2").args(&[ - Arg::new("help") - .long("help") - .short('h') - .help("Print help message") - .action(ArgAction::Help), - Arg::new("flag_b") - .long("flag_b") - .help("first flag") - .action(ArgAction::SetTrue), - Arg::new("flag_a") - .long("flag_a") - .help("second flag") - .action(ArgAction::SetTrue), - ]), - ); - - utils::assert_output( - cmd, - "test sub --help", - PREFER_USER_HELP_SUBCMD_DERIVE_ORDER, - false, - ); -} - #[test] fn subcommand_sorted_display_order() { static SUBCMD_ALPHA_ORDER: &str = "test 1 diff --git a/tests/builder/flag_subcommands.rs b/tests/builder/flag_subcommands.rs index 0abbabf5f11..7b2601d10bb 100644 --- a/tests/builder/flag_subcommands.rs +++ b/tests/builder/flag_subcommands.rs @@ -420,6 +420,7 @@ fn flag_subcommand_long_conflict_with_arg() { } #[test] +#[should_panic = "the '--help' long flag for the 'help' argument conflicts with the short flag for 'help' subcommand"] fn flag_subcommand_conflict_with_help() { let _ = Command::new("test") .subcommand(Command::new("help").short_flag('h').long_flag("help")) @@ -428,8 +429,11 @@ fn flag_subcommand_conflict_with_help() { } #[test] +#[cfg(debug_assertions)] +#[should_panic = "the '--version' long flag for the 'version' argument conflicts with the short flag for 'ver' subcommand"] fn flag_subcommand_conflict_with_version() { let _ = Command::new("test") + .version("1.0.0") .subcommand(Command::new("ver").short_flag('V').long_flag("version")) .try_get_matches_from(vec!["myprog", "--version"]) .unwrap(); diff --git a/tests/builder/groups.rs b/tests/builder/groups.rs index 30981ac8f61..3c32ea99966 100644 --- a/tests/builder/groups.rs +++ b/tests/builder/groups.rs @@ -87,7 +87,7 @@ fn arg_group_new_of_arg_name() { fn group_single_value() { let res = Command::new("group") .arg(arg!(-c --color [color] "some option")) - .arg(arg!(-h --hostname "another option").required(false)) + .arg(arg!(-n --hostname "another option").required(false)) .group(ArgGroup::new("grp").args(&["hostname", "color"])) .try_get_matches_from(vec!["", "-c", "blue"]); assert!(res.is_ok(), "{}", res.unwrap_err()); @@ -104,7 +104,7 @@ fn group_single_value() { fn group_empty() { let res = Command::new("group") .arg(arg!(-c --color [color] "some option")) - .arg(arg!(-h --hostname "another option").required(false)) + .arg(arg!(-n --hostname "another option").required(false)) .group(ArgGroup::new("grp").args(&["hostname", "color"])) .try_get_matches_from(vec![""]); assert!(res.is_ok(), "{}", res.unwrap_err()); @@ -118,7 +118,7 @@ fn group_empty() { fn group_required_flags_empty() { let result = Command::new("group") .arg(arg!(-c --color "some option")) - .arg(arg!(-h --hostname "another option").required(false)) + .arg(arg!(-n --hostname "another option").required(false)) .group( ArgGroup::new("grp") .required(true) @@ -134,7 +134,7 @@ fn group_required_flags_empty() { fn group_multi_value_single_arg() { let res = Command::new("group") .arg(arg!(-c --color "some option").num_args(1..)) - .arg(arg!(-h --hostname "another option").required(false)) + .arg(arg!(-n --hostname "another option").required(false)) .group(ArgGroup::new("grp").args(&["hostname", "color"])) .try_get_matches_from(vec!["", "-c", "blue", "red", "green"]); assert!(res.is_ok(), "{:?}", res.unwrap_err().kind()); diff --git a/tests/builder/help.rs b/tests/builder/help.rs index e61d5c714e4..5a208fd1d67 100644 --- a/tests/builder/help.rs +++ b/tests/builder/help.rs @@ -1248,7 +1248,8 @@ OPTIONS: fn override_help_short() { let cmd = Command::new("test") .version("0.1") - .mut_arg("help", |h| h.short('H')); + .arg(arg!(-H --help "Print help information")) + .disable_help_flag(true); utils::assert_output(cmd.clone(), "test --help", OVERRIDE_HELP_SHORT, false); utils::assert_output(cmd, "test -H", OVERRIDE_HELP_SHORT, false); @@ -1268,7 +1269,8 @@ OPTIONS: fn override_help_long() { let cmd = Command::new("test") .version("0.1") - .mut_arg("help", |h| h.long("hell")); + .arg(arg!(-h --hell "Print help information").action(ArgAction::Help)) + .disable_help_flag(true); utils::assert_output(cmd.clone(), "test --hell", OVERRIDE_HELP_LONG, false); utils::assert_output(cmd, "test -h", OVERRIDE_HELP_LONG, false); @@ -1280,7 +1282,7 @@ USAGE: test OPTIONS: - -h, --help Print help information + -h, --help Print custom help information -V, --version Print version information "; @@ -1288,37 +1290,42 @@ OPTIONS: fn override_help_about() { let cmd = Command::new("test") .version("0.1") - .mut_arg("help", |h| h.help("Print help information")); + .arg(arg!(-h --help "Print custom help information")) + .disable_help_flag(true); utils::assert_output(cmd.clone(), "test --help", OVERRIDE_HELP_ABOUT, false); utils::assert_output(cmd, "test -h", OVERRIDE_HELP_ABOUT, false); } #[test] -fn arg_short_conflict_with_help() { - static HELP_CONFLICT: &str = "conflict - -USAGE: - conflict [OPTIONS] - -OPTIONS: - -h - --help Print help information -"; - - let cmd = Command::new("conflict").arg(Arg::new("home").short('h').action(ArgAction::SetTrue)); - - utils::assert_output(cmd, "conflict --help", HELP_CONFLICT, false); +#[cfg(debug_assertions)] +#[should_panic = "Command conflict: Argument names must be unique, but 'help' is in use by more than one argument or group (call `cmd.disable_help_flag(true)` to remove the auto-generated `--help`)"] +fn arg_id_conflict_with_help() { + Command::new("conflict") + .arg(Arg::new("help").short('?').action(ArgAction::SetTrue)) + .build(); } +#[test] #[cfg(debug_assertions)] +#[should_panic = "Command conflict: Short option names must be unique for each argument, but '-h' is in use by both 'home' and 'help' (call `cmd.disable_help_flag(true)` to remove the auto-generated `--help`)"] +fn arg_short_conflict_with_help() { + Command::new("conflict") + .arg(Arg::new("home").short('h').action(ArgAction::SetTrue)) + .build(); +} + #[test] -#[should_panic = "`help`s `-h` conflicts with `home`."] -fn arg_short_conflict_with_help_mut_arg() { - let _ = Command::new("conflict") - .arg(Arg::new("home").short('h')) - .mut_arg("help", |h| h.short('h')) - .try_get_matches_from(vec![""]); +#[cfg(debug_assertions)] +#[should_panic = "Command conflict: Long option names must be unique for each argument, but '--help' is in use by both 'custom-help' and 'help' (call `cmd.disable_help_flag(true)` to remove the auto-generated `--help`)"] +fn arg_long_conflict_with_help() { + Command::new("conflict") + .arg( + Arg::new("custom-help") + .long("help") + .action(ArgAction::SetTrue), + ) + .build(); } #[test] @@ -1519,6 +1526,7 @@ OPTIONS: fn issue_1112_setup() -> Command<'static> { Command::new("test") .version("1.3") + .disable_help_flag(true) .arg( Arg::new("help1") .long("help") @@ -2048,7 +2056,9 @@ fn after_help_no_args() { assert_eq!(help, AFTER_HELP_NO_ARGS); } -static HELP_SUBCMD_HELP: &str = "myapp-help +#[test] +fn help_subcmd_help() { + static HELP_SUBCMD_HELP: &str = "myapp-help Print this message or the help of the given subcommand(s) USAGE: @@ -2056,21 +2066,17 @@ USAGE: ARGS: ... The subcommand whose help message to display - -OPTIONS: - -h, --help Print custom help text "; -#[test] -fn help_subcmd_help() { let cmd = Command::new("myapp") - .mut_arg("help", |h| h.help("Print custom help text")) .subcommand(Command::new("subcmd").subcommand(Command::new("multi").version("1.0"))); utils::assert_output(cmd.clone(), "myapp help help", HELP_SUBCMD_HELP, false); } -static SUBCMD_HELP_SUBCMD_HELP: &str = "myapp-subcmd-help +#[test] +fn subcmd_help_subcmd_help() { + static SUBCMD_HELP_SUBCMD_HELP: &str = "myapp-subcmd-help Print this message or the help of the given subcommand(s) USAGE: @@ -2078,15 +2084,9 @@ USAGE: ARGS: ... The subcommand whose help message to display - -OPTIONS: - -h, --help Print custom help text "; -#[test] -fn subcmd_help_subcmd_help() { let cmd = Command::new("myapp") - .mut_arg("help", |h| h.help("Print custom help text")) .subcommand(Command::new("subcmd").subcommand(Command::new("multi").version("1.0"))); utils::assert_output( @@ -2097,79 +2097,6 @@ fn subcmd_help_subcmd_help() { ); } -static HELP_ABOUT_MULTI_SC: &str = "myapp-subcmd-multi 1.0 - -USAGE: - myapp subcmd multi - -OPTIONS: - -h, --help Print custom help text - -V, --version Print version information -"; - -static HELP_ABOUT_MULTI_SC_OVERRIDE: &str = "myapp-subcmd-multi 1.0 - -USAGE: - myapp subcmd multi - -OPTIONS: - -h, --help Print custom help text from multi - -V, --version Print version information -"; - -#[test] -fn help_about_multi_subcmd() { - let cmd = Command::new("myapp") - .mut_arg("help", |h| h.help("Print custom help text")) - .subcommand(Command::new("subcmd").subcommand(Command::new("multi").version("1.0"))); - - utils::assert_output( - cmd.clone(), - "myapp help subcmd multi", - HELP_ABOUT_MULTI_SC, - false, - ); - utils::assert_output( - cmd.clone(), - "myapp subcmd multi -h", - HELP_ABOUT_MULTI_SC, - false, - ); - utils::assert_output(cmd, "myapp subcmd multi --help", HELP_ABOUT_MULTI_SC, false); -} - -#[test] -fn help_about_multi_subcmd_override() { - let cmd = Command::new("myapp") - .mut_arg("help", |h| h.help("Print custom help text")) - .subcommand( - Command::new("subcmd").subcommand( - Command::new("multi") - .version("1.0") - .mut_arg("help", |h| h.help("Print custom help text from multi")), - ), - ); - - utils::assert_output( - cmd.clone(), - "myapp help subcmd multi", - HELP_ABOUT_MULTI_SC_OVERRIDE, - false, - ); - utils::assert_output( - cmd.clone(), - "myapp subcmd multi -h", - HELP_ABOUT_MULTI_SC_OVERRIDE, - false, - ); - utils::assert_output( - cmd, - "myapp subcmd multi --help", - HELP_ABOUT_MULTI_SC_OVERRIDE, - false, - ); -} - #[test] fn option_usage_order() { static OPTION_USAGE_ORDER: &str = "order @@ -2309,7 +2236,8 @@ fn only_custom_heading_opts_no_args() { let cmd = Command::new("test") .version("1.4") .disable_version_flag(true) - .mut_arg("help", |a| a.hide(true)) + .disable_help_flag(true) + .arg(arg!(--help).hide(true)) .next_help_heading(Some("NETWORKING")) .arg(arg!(-s --speed "How fast").required(false)); @@ -2330,7 +2258,8 @@ fn only_custom_heading_pos_no_args() { let cmd = Command::new("test") .version("1.4") .disable_version_flag(true) - .mut_arg("help", |a| a.hide(true)) + .disable_help_flag(true) + .arg(arg!(--help).hide(true)) .next_help_heading(Some("NETWORKING")) .arg(Arg::new("speed").help("How fast")); @@ -2608,7 +2537,8 @@ fn override_help_subcommand() { fn override_help_flag_using_long() { let cmd = Command::new("foo") .subcommand(Command::new("help").long_flag("help")) - .disable_help_flag(true); + .disable_help_flag(true) + .disable_help_subcommand(true); let matches = cmd.try_get_matches_from(&["foo", "--help"]).unwrap(); assert!(matches.subcommand_matches("help").is_some()); } @@ -2617,6 +2547,7 @@ fn override_help_flag_using_long() { fn override_help_flag_using_short() { let cmd = Command::new("foo") .disable_help_flag(true) + .disable_help_subcommand(true) .subcommand(Command::new("help").short_flag('h')); let matches = cmd.try_get_matches_from(&["foo", "-h"]).unwrap(); assert!(matches.subcommand_matches("help").is_some()); @@ -2693,7 +2624,8 @@ ARGS: fn help_without_short() { let mut cmd = clap::Command::new("test") .arg(arg!(-h --hex )) - .arg(arg!(--help)); + .arg(arg!(--help)) + .disable_help_flag(true); cmd.build(); let help = cmd.get_arguments().find(|a| a.get_id() == "help").unwrap(); diff --git a/tests/builder/hidden_args.rs b/tests/builder/hidden_args.rs index 80e7e3f87de..588c3124ccc 100644 --- a/tests/builder/hidden_args.rs +++ b/tests/builder/hidden_args.rs @@ -246,8 +246,10 @@ fn hide_opt_args_only() { let cmd = Command::new("test") .version("1.4") .after_help("After help") - .mut_arg("help", |a| a.hide(true)) - .mut_arg("version", |a| a.hide(true)) + .disable_help_flag(true) + .disable_version_flag(true) + .arg(arg!(-h - -help).hide(true)) + .arg(arg!(-v - -version).hide(true)) .arg( arg!(--option "some option") .required(false) @@ -270,8 +272,10 @@ fn hide_pos_args_only() { let cmd = Command::new("test") .version("1.4") .after_help("After help") - .mut_arg("help", |a| a.hide(true)) - .mut_arg("version", |a| a.hide(true)) + .disable_help_flag(true) + .disable_version_flag(true) + .arg(arg!(-h - -help).hide(true)) + .arg(arg!(-v - -version).hide(true)) .args(&[Arg::new("pos").help("some pos").hide(true)]); utils::assert_output(cmd, "test --help", HIDDEN_POS_ARGS_ONLY, false); @@ -290,8 +294,10 @@ fn hide_subcmds_only() { let cmd = Command::new("test") .version("1.4") .after_help("After help") - .mut_arg("help", |a| a.hide(true)) - .mut_arg("version", |a| a.hide(true)) + .disable_help_flag(true) + .disable_version_flag(true) + .arg(arg!(-h - -help).hide(true)) + .arg(arg!(-v - -version).hide(true)) .subcommand(Command::new("sub").hide(true)); utils::assert_output(cmd, "test --help", HIDDEN_SUBCMDS_ONLY, false); diff --git a/tests/builder/version.rs b/tests/builder/version.rs index 2dc78292299..317c9933b0e 100644 --- a/tests/builder/version.rs +++ b/tests/builder/version.rs @@ -1,8 +1,4 @@ -use super::utils; - -use std::str; - -use clap::{error::ErrorKind, Arg, ArgAction, Command}; +use clap::{error::ErrorKind, ArgAction, Command}; fn common() -> Command<'static> { Command::new("foo") @@ -79,88 +75,25 @@ fn version_flag_from_long_version_long() { } #[test] +#[cfg(debug_assertions)] +#[should_panic = "Command foo: Long option names must be unique for each argument, but '--version' is in use by both 'ver' and 'version' (call `cmd.disable_version_flag(true)` to remove the auto-generated `--version`)"] fn override_version_long_with_user_flag() { - let res = with_version() - .arg(Arg::new("ver").long("version").action(ArgAction::SetTrue)) - .try_get_matches_from("foo --version".split(' ')); - - assert!(res.is_ok(), "{}", res.unwrap_err()); - let m = res.unwrap(); - assert!(*m.get_one::("ver").expect("defaulted by clap")); -} - -#[test] -fn override_version_long_with_user_flag_no_version_flag() { - let res = with_version() - .arg(Arg::new("ver").long("version")) - .try_get_matches_from("foo -V".split(' ')); - - assert!(res.is_err()); - let err = res.unwrap_err(); - assert_eq!(err.kind(), ErrorKind::UnknownArgument); + with_version() + .arg( + clap::Arg::new("ver") + .long("version") + .action(ArgAction::SetTrue), + ) + .debug_assert(); } #[test] +#[cfg(debug_assertions)] +#[should_panic = "Command foo: Short option names must be unique for each argument, but '-V' is in use by both 'ver' and 'version' (call `cmd.disable_version_flag(true)` to remove the auto-generated `--version`)"] fn override_version_short_with_user_flag() { - let res = with_version() - .arg(Arg::new("ver").short('V').action(ArgAction::SetTrue)) - .try_get_matches_from("foo -V".split(' ')); - - assert!(res.is_ok(), "{}", res.unwrap_err()); - let m = res.unwrap(); - assert!(*m.get_one::("ver").expect("defaulted by clap")); -} - -#[test] -fn override_version_short_with_user_flag_long_still_works() { - let res = with_version() - .arg(Arg::new("ver").short('V')) - .try_get_matches_from("foo --version".split(' ')); - - assert!(res.is_err()); - let err = res.unwrap_err(); - assert_eq!(err.kind(), ErrorKind::DisplayVersion); -} - -#[test] -fn mut_version_short() { - let res = with_version() - .mut_arg("version", |a| a.short('z')) - .try_get_matches_from("foo -z".split(' ')); - - assert!(res.is_err()); - let err = res.unwrap_err(); - assert_eq!(err.kind(), ErrorKind::DisplayVersion); -} - -#[test] -fn mut_version_long() { - let res = with_version() - .mut_arg("version", |a| a.long("qux")) - .try_get_matches_from("foo --qux".split(' ')); - - assert!(res.is_err()); - let err = res.unwrap_err(); - assert_eq!(err.kind(), ErrorKind::DisplayVersion); -} - -static VERSION_ABOUT_MULTI_SC: &str = "foo-bar-baz 3.0 - -USAGE: - foo bar baz - -OPTIONS: - -h, --help Print help information - -V, --version Print custom version about text -"; - -#[test] -fn version_about_multi_subcmd() { - let cmd = with_subcommand() - .mut_arg("version", |a| a.help("Print custom version about text")) - .propagate_version(true); - - utils::assert_output(cmd, "foo bar baz -h", VERSION_ABOUT_MULTI_SC, false); + with_version() + .arg(clap::Arg::new("ver").short('V').action(ArgAction::SetTrue)) + .debug_assert(); } #[test]