denoland/deno · #36722

fix(cli): don't duplicate passthrough args for deno deploy/sandbox

bartlomieju · merged Aug 28, 20262 files · 79 + / 5
libs/cli_parser/src/convert.rs6 + / 5
@@ -211,8 +211,8 @@ pub fn convert(result: ParseResult) -> Result<Flags, CliError> {     Some("types") => types_parse(&mut flags),     Some("lsp") => lsp_parse(&mut flags),     Some("vendor") => vendor_parse(&mut flags),-    Some("deploy") => deploy_parse(&result, &mut flags, false),-    Some("sandbox") => deploy_parse(&result, &mut flags, true),+    Some("deploy") => deploy_parse(&mut flags, false),+    Some("sandbox") => deploy_parse(&mut flags, true),     Some("bundle") => bundle_parse(&result, &mut flags),     Some("audit") => audit_parse(&result, &mut flags)?,     Some("why") => why_parse(&result, &mut flags),@@ -2960,9 +2960,10 @@ fn vendor_parse(flags: &mut Flags) {   flags.subcommand = DenoSubcommand::Vendor; } -fn deploy_parse(result: &ParseResult, flags: &mut Flags, sandbox: bool) {-  // deploy/sandbox are passthrough - all args go into argv-  flags.argv = result.trailing.clone();+fn deploy_parse(flags: &mut Flags, sandbox: bool) {+  // deploy/sandbox are passthrough - all args go into argv. Note that argv is+  // filled in by the shared trailing-arg handling in `flags_from_vec`, so this+  // must not copy `result.trailing` itself or every arg would be duplicated.   flags.subcommand = DenoSubcommand::Deploy(DeployFlags { sandbox }); } 
libs/cli_parser/src/tests_full.rs73 + / 0
@@ -9767,6 +9767,79 @@ fn use_env_proxy_flags() {   assert!(r.is_err()); } +#[test]+fn deploy_subcommand() {+  let r = flags_from_vec(svec!["deno", "deploy"]);+  assert_eq!(+    r.unwrap(),+    Flags {+      subcommand: DenoSubcommand::Deploy(DeployFlags { sandbox: false }),+      ..Flags::default()+    }+  );++  // `deploy` is a passthrough subcommand: every arg after it is forwarded+  // verbatim, exactly once. Regression test for a duplication bug where the+  // args were written to `argv` both by `deploy_parse` and by the generic+  // trailing-arg handling, turning `--prod` into `--prod --prod`.+  let r = flags_from_vec(svec!["deno", "deploy", "--prod"]);+  assert_eq!(+    r.unwrap(),+    Flags {+      subcommand: DenoSubcommand::Deploy(DeployFlags { sandbox: false }),+      argv: svec!["--prod"],+      ..Flags::default()+    }+  );++  let r =+    flags_from_vec(svec!["deno", "deploy", "--project=myapp", "--prod", "-y"]);+  assert_eq!(+    r.unwrap(),+    Flags {+      subcommand: DenoSubcommand::Deploy(DeployFlags { sandbox: false }),+      argv: svec!["--project=myapp", "--prod", "-y"],+      ..Flags::default()+    }+  );+}++#[test]+fn deploy_subcommand_passthrough_is_verbatim() {+  // Everything after the subcommand is handed to deployctl untouched, so+  // `--`, deno-looking flags and repeated flags must all survive as-is+  // rather than being interpreted (or duplicated) by the deno parser.+  let r = flags_from_vec(svec![+    "deno",+    "deploy",+    "--prod",+    "--",+    "--allow-net",+    "-A"+  ]);+  assert_eq!(+    r.unwrap(),+    Flags {+      subcommand: DenoSubcommand::Deploy(DeployFlags { sandbox: false }),+      argv: svec!["--prod", "--", "--allow-net", "-A"],+      ..Flags::default()+    }+  );+}++#[test]+fn deploy_sandbox_subcommand() {+  let r = flags_from_vec(svec!["deno", "sandbox", "--prod", "arg"]);+  assert_eq!(+    r.unwrap(),+    Flags {+      subcommand: DenoSubcommand::Deploy(DeployFlags { sandbox: true }),+      argv: svec!["--prod", "arg"],+      ..Flags::default()+    }+  );+}+ #[test] fn bundle_sourcemap_bare_does_not_consume_entrypoint() {   // `--sourcemap` takes an optional value that must be attached with `=`.