Skip to content

Commit

Permalink
fix: error out if a valid flag is passed before a subcommand (#25830)
Browse files Browse the repository at this point in the history
Closes #25808
  • Loading branch information
crowlKats authored Sep 23, 2024
1 parent 33f169b commit 1eebd20
Showing 1 changed file with 62 additions and 10 deletions.
72 changes: 62 additions & 10 deletions cli/args/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1233,6 +1233,51 @@ pub fn flags_from_vec(args: Vec<OsString>) -> clap::error::Result<Flags> {
}

if let Some((subcommand, mut m)) = matches.remove_subcommand() {
let pre_subcommand_arg = app
.get_arguments()
.filter(|arg| !arg.is_global_set())
.find(|arg| {
matches
.value_source(arg.get_id().as_str())
.is_some_and(|value| value == clap::parser::ValueSource::CommandLine)
})
.map(|arg| {
format!(
"--{}",
arg.get_long().unwrap_or_else(|| arg.get_id().as_str())
)
});

if let Some(arg) = pre_subcommand_arg {
let usage = app.find_subcommand_mut(&subcommand).unwrap().render_usage();

let mut err =
clap::error::Error::new(ErrorKind::UnknownArgument).with_cmd(&app);
err.insert(
clap::error::ContextKind::InvalidArg,
clap::error::ContextValue::String(arg.clone()),
);

let valid = app.get_styles().get_valid();

let styled_suggestion = clap::builder::StyledStr::from(format!(
"'{}{subcommand} {arg}{}' exists",
valid.render(),
valid.render_reset()
));

err.insert(
clap::error::ContextKind::Suggested,
clap::error::ContextValue::StyledStrs(vec![styled_suggestion]),
);
err.insert(
clap::error::ContextKind::Usage,
clap::error::ContextValue::StyledStr(usage),
);

return Err(err);
}

match subcommand.as_str() {
"add" => add_parse(&mut flags, &mut m),
"remove" => remove_parse(&mut flags, &mut m),
Expand Down Expand Up @@ -4695,16 +4740,10 @@ fn run_parse(
"[SCRIPT_ARG] may only be omitted with --v8-flags=--help, else to use the repl with arguments, please use the `deno repl` subcommand",
));
} else {
return Err(
app
.get_subcommands_mut()
.find(|subcommand| subcommand.get_name() == "run")
.unwrap()
.error(
clap::error::ErrorKind::MissingRequiredArgument,
"[SCRIPT_ARG] may only be omitted with --v8-flags=--help",
),
);
return Err(app.find_subcommand_mut("run").unwrap().error(
clap::error::ErrorKind::MissingRequiredArgument,
"[SCRIPT_ARG] may only be omitted with --v8-flags=--help",
));
}

Ok(())
Expand Down Expand Up @@ -10799,4 +10838,17 @@ mod tests {
}
)
}

#[test]
fn flag_before_subcommand() {
let r = flags_from_vec(svec!["deno", "--allow-net", "repl"]);
assert_eq!(
r.unwrap_err().to_string(),
"error: unexpected argument '--allow-net' found
tip: 'repl --allow-net' exists
Usage: deno repl [OPTIONS] [-- [ARGS]...]\n"
)
}
}

0 comments on commit 1eebd20

Please sign in to comment.