summaryrefslogtreecommitdiff
path: root/cli/args
diff options
context:
space:
mode:
authorLeo Kettmeir <crowlkats@toaxl.com>2024-09-23 16:01:05 -0700
committerGitHub <noreply@github.com>2024-09-23 16:01:05 -0700
commit1eebd207250afbefaeeff1e889bc6962474a15fa (patch)
tree752f974cf878de58304de76d86f88daca5ba26e6 /cli/args
parent33f169beb90814b7f2f62a8c0e3990722ae3db4c (diff)
fix: error out if a valid flag is passed before a subcommand (#25830)
Closes #25808
Diffstat (limited to 'cli/args')
-rw-r--r--cli/args/flags.rs72
1 files changed, 62 insertions, 10 deletions
diff --git a/cli/args/flags.rs b/cli/args/flags.rs
index 8490fdab6..d325ce7bc 100644
--- a/cli/args/flags.rs
+++ b/cli/args/flags.rs
@@ -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),
@@ -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(())
@@ -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"
+ )
+ }
}