From 55437026fc2b06199f7e338e899ded7ea73dfff1 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 17 Oct 2022 16:29:08 +0200 Subject: [PATCH] cargo-apk: Reimplement "default" subcommand trailing args for `cargo` with `--` separator `clap` [does not currently support] parsing unknown arguments into a side `Vec`, which is exactly what `cargo apk --` needs to parse a few known `cargo` arguments (such as `--target` and `-p`) but forward the rest verbatim to the underlying `cargo` subcommand. `allow_hyphen_values = true` could partially help us out with this, but it parses all remaining arguments into that `Vec` upon encountering the first unknown flag/arg, resulting in all known flags after that to also be treated as "unknown" instead of filling up our `args: Args` struct. Since [a workaround for this isn't currently functioning], introduce pure trailing args with an additional `--` separator to make it clear which arguments go to `cargo-apk` (and are almost all, except `--device`, forwarded to `cargo`) and which are only passed to `cargo `. [does not currently support]: https://github.com/clap-rs/clap/issues/1404 [a workaround for this isn't currently functioning]: https://github.com/clap-rs/clap/issues/1404#issuecomment-1309254274 --- cargo-apk/src/apk.rs | 6 +++++- cargo-apk/src/main.rs | 20 +++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/cargo-apk/src/apk.rs b/cargo-apk/src/apk.rs index 3a625d6d..ceb7cb65 100644 --- a/cargo-apk/src/apk.rs +++ b/cargo-apk/src/apk.rs @@ -306,7 +306,7 @@ impl<'a> ApkBuilder<'a> { Ok(()) } - pub fn default(&self, cargo_cmd: &str) -> Result<(), Error> { + pub fn default(&self, cargo_cmd: &str, cargo_args: &[String]) -> Result<(), Error> { for target in &self.build_targets { let mut cargo = cargo_ndk( &self.ndk, @@ -322,6 +322,10 @@ impl<'a> ApkBuilder<'a> { cargo.arg("--target").arg(triple); } + for additional_arg in cargo_args { + cargo.arg(additional_arg); + } + if !cargo.status()?.success() { return Err(NdkError::CmdFailed(cargo).into()); } diff --git a/cargo-apk/src/main.rs b/cargo-apk/src/main.rs index 8ad81b19..315bf5c2 100644 --- a/cargo-apk/src/main.rs +++ b/cargo-apk/src/main.rs @@ -27,7 +27,6 @@ struct Args { } #[derive(clap::Subcommand)] -#[clap(trailing_var_arg = true)] enum ApkSubCmd { /// Analyze the current package and report errors, but don't build object files nor an apk #[clap(visible_alias = "c")] @@ -44,9 +43,20 @@ enum ApkSubCmd { /// Invoke `cargo` under the detected NDK environment #[clap(name = "--")] Ndk { + /// `cargo` subcommand to run cargo_cmd: String, + + /// Arguments used to deduce the current environment. Also passed to `cargo` #[clap(flatten)] args: Args, + + /// Additional arguments passed to `cargo` + // TODO: Arguments in this vec should be intermixable with other arguments; + // this is somewhat possible with `allow_hyphen_values = true` but any argument + // after the first unknown arg/flag ends up inside `cargo_args` instead of being + // parsed into `args: Args`. + #[clap(trailing_var_arg = true, last = true)] + cargo_args: Vec, }, /// Run a binary or example apk of the local package #[clap(visible_alias = "r")] @@ -84,10 +94,14 @@ fn main() -> anyhow::Result<()> { builder.build(artifact)?; } } - ApkSubCmd::Ndk { cargo_cmd, args } => { + ApkSubCmd::Ndk { + cargo_cmd, + args, + cargo_args, + } => { let cmd = Subcommand::new(args.subcommand_args)?; let builder = ApkBuilder::from_subcommand(&cmd, args.device)?; - builder.default(&cargo_cmd)?; + builder.default(&cargo_cmd, &cargo_args)?; } ApkSubCmd::Run { args, no_logcat } => { let cmd = Subcommand::new(args.subcommand_args)?;