Skip to content

Commit

Permalink
Merge pull request #5033 from epage/escape
Browse files Browse the repository at this point in the history
fix(parser): Don't suggest -- as often
  • Loading branch information
epage authored Jul 21, 2023
2 parents 55923ca + 6590a85 commit e822341
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 16 deletions.
25 changes: 15 additions & 10 deletions clap_builder/src/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ impl<F: ErrorFormatter> Error<F> {
subcmd: String,
did_you_mean: Vec<String>,
name: String,
suggested_trailing_arg: bool,
usage: Option<StyledStr>,
) -> Self {
use std::fmt::Write as _;
Expand All @@ -456,15 +457,19 @@ impl<F: ErrorFormatter> Error<F> {

#[cfg(feature = "error-context")]
{
let mut styled_suggestion = StyledStr::new();
let _ = write!(
styled_suggestion,
"to pass '{}{subcmd}{}' as a value, use '{}{name} -- {subcmd}{}'",
invalid.render(),
invalid.render_reset(),
valid.render(),
valid.render_reset()
);
let mut suggestions = vec![];
if suggested_trailing_arg {
let mut styled_suggestion = StyledStr::new();
let _ = write!(
styled_suggestion,
"to pass '{}{subcmd}{}' as a value, use '{}{name} -- {subcmd}{}'",
invalid.render(),
invalid.render_reset(),
valid.render(),
valid.render_reset()
);
suggestions.push(styled_suggestion);
}

err = err.extend_context_unchecked([
(ContextKind::InvalidSubcommand, ContextValue::String(subcmd)),
Expand All @@ -474,7 +479,7 @@ impl<F: ErrorFormatter> Error<F> {
),
(
ContextKind::Suggested,
ContextValue::StyledStrs(vec![styled_suggestion]),
ContextValue::StyledStrs(suggestions),
),
]);
if let Some(usage) = usage {
Expand Down
8 changes: 5 additions & 3 deletions clap_builder/src/parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,10 @@ impl<'cmd> Parser<'cmd> {
}
}

let suggested_trailing_arg = !trailing_values
&& self.cmd.has_positionals()
&& (arg_os.is_long() || arg_os.is_short());

if !(self.cmd.is_args_conflicts_with_subcommands_set() && valid_arg_found) {
let candidates = suggestions::did_you_mean(
&arg_os.display().to_string(),
Expand All @@ -489,6 +493,7 @@ impl<'cmd> Parser<'cmd> {
.get_bin_name()
.unwrap_or_else(|| self.cmd.get_name())
.to_owned(),
suggested_trailing_arg,
Usage::new(self.cmd).create_usage_with_title(&[]),
);
}
Expand All @@ -505,9 +510,6 @@ impl<'cmd> Parser<'cmd> {
}
}

let suggested_trailing_arg = !trailing_values
&& self.cmd.has_positionals()
&& (arg_os.is_long() || arg_os.is_short());
ClapError::unknown_argument(
self.cmd,
arg_os.display().to_string(),
Expand Down
22 changes: 22 additions & 0 deletions tests/builder/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,25 @@ For more information, try '--help'.
";
assert_error(err, expected_kind, MESSAGE, true);
}

#[test]
#[cfg(feature = "error-context")]
#[cfg(feature = "suggestions")]
fn cant_use_trailing_subcommand() {
let cmd = Command::new("test").subcommand(Command::new("bar"));

let res = cmd.try_get_matches_from(["test", "baz"]);
assert!(res.is_err());
let err = res.unwrap_err();
let expected_kind = ErrorKind::InvalidSubcommand;
static MESSAGE: &str = "\
error: unrecognized subcommand 'baz'
tip: a similar subcommand exists: 'bar'
Usage: test [COMMAND]
For more information, try '--help'.
";
assert_error(err, expected_kind, MESSAGE, true);
}
3 changes: 0 additions & 3 deletions tests/builder/subcommands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ fn subcmd_did_you_mean_output() {
error: unrecognized subcommand 'subcm'
tip: a similar subcommand exists: 'subcmd'
tip: to pass 'subcm' as a value, use 'dym -- subcm'
Usage: dym [COMMAND]
Expand All @@ -123,7 +122,6 @@ fn subcmd_did_you_mean_output_ambiguous() {
error: unrecognized subcommand 'te'
tip: some similar subcommands exist: 'test', 'temp'
tip: to pass 'te' as a value, use 'dym -- te'
Usage: dym [COMMAND]
Expand Down Expand Up @@ -504,7 +502,6 @@ For more information, try 'help'.
error: unrecognized subcommand 'baz'
tip: a similar subcommand exists: 'bar'
tip: to pass 'baz' as a value, use ' -- baz'
Usage: <COMMAND>
Expand Down

0 comments on commit e822341

Please sign in to comment.