Skip to content

Commit

Permalink
Update to cargo-subcommand 0.8.0 with clap argument parser (#238)
Browse files Browse the repository at this point in the history
Co-authored-by: Marijn Suijten <[email protected]>
  • Loading branch information
dvc94ch and MarijnS95 authored Sep 23, 2022
1 parent 282ea1d commit b488fb9
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 109 deletions.
5 changes: 3 additions & 2 deletions cargo-apk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ repository = "https://github.com/rust-windowing/android-ndk-rs"

[dependencies]
anyhow = "1.0.57"
cargo-subcommand = "0.7"
cargo-subcommand = "0.8"
clap = { version = "3", features = ["derive"] }
dunce = "1"
env_logger = "0.9"
log = "0.4"
ndk-build = { path = "../ndk-build", version = "0.8.0" }
serde = "1"
thiserror = "1.0.31"
thiserror = "1"
toml = "0.5"
24 changes: 9 additions & 15 deletions cargo-apk/src/apk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,12 @@ pub struct ApkBuilder<'a> {
build_dir: PathBuf,
build_targets: Vec<Target>,
device_serial: Option<String>,
no_logcat: bool,
}

impl<'a> ApkBuilder<'a> {
pub fn from_subcommand(
cmd: &'a Subcommand,
device_serial: Option<String>,
no_logcat: bool,
) -> Result<Self, Error> {
let ndk = Ndk::from_env()?;
let mut manifest = Manifest::parse_from_toml(cmd.manifest())?;
Expand Down Expand Up @@ -101,7 +99,6 @@ impl<'a> ApkBuilder<'a> {
build_dir,
build_targets,
device_serial,
no_logcat,
})
}

Expand All @@ -118,7 +115,7 @@ impl<'a> ApkBuilder<'a> {
let triple = target.rust_triple();
cargo.arg("--target").arg(triple);
}
cargo.args(self.cmd.args());
self.cmd.args().apply(&mut cargo);
if !cargo.status()?.success() {
return Err(NdkError::CmdFailed(cargo).into());
}
Expand Down Expand Up @@ -184,12 +181,8 @@ impl<'a> ApkBuilder<'a> {

for target in &self.build_targets {
let triple = target.rust_triple();
let build_dir = dunce::simplified(self.cmd.target_dir())
.join(triple)
.join(self.cmd.profile());
let artifact = build_dir
.join(artifact)
.join(artifact.file_name(CrateType::Cdylib, triple));
let build_dir = self.cmd.build_dir(Some(triple));
let artifact = self.cmd.artifact(artifact, Some(triple), CrateType::Cdylib);

let mut cargo = cargo_ndk(
&self.ndk,
Expand All @@ -201,7 +194,7 @@ impl<'a> ApkBuilder<'a> {
if self.cmd.target().is_none() {
cargo.arg("--target").arg(triple);
}
cargo.args(self.cmd.args());
self.cmd.args().apply(&mut cargo);

if !cargo.status()?.success() {
return Err(NdkError::CmdFailed(cargo).into());
Expand Down Expand Up @@ -243,12 +236,12 @@ impl<'a> ApkBuilder<'a> {
Ok(apk.add_pending_libs_and_align()?.sign(signing_key)?)
}

pub fn run(&self, artifact: &Artifact) -> Result<(), Error> {
pub fn run(&self, artifact: &Artifact, no_logcat: bool) -> Result<(), Error> {
let apk = self.build(artifact)?;
apk.install(self.device_serial.as_deref())?;
let pid = apk.start(self.device_serial.as_deref())?;

if !self.no_logcat {
if !no_logcat {
self.ndk
.adb(self.device_serial.as_deref())?
.arg("logcat")
Expand All @@ -275,15 +268,16 @@ impl<'a> ApkBuilder<'a> {
Ok(())
}

pub fn default(&self) -> Result<(), Error> {
pub fn default(&self, cargo_cmd: &str) -> Result<(), Error> {
for target in &self.build_targets {
let mut cargo = cargo_ndk(
&self.ndk,
*target,
self.min_sdk_version(),
self.cmd.target_dir(),
)?;
cargo.args(self.cmd.args());
cargo.arg(cargo_cmd);
self.cmd.args().apply(&mut cargo);

if self.cmd.target().is_none() {
let triple = target.rust_triple();
Expand Down
181 changes: 89 additions & 92 deletions cargo-apk/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,112 +1,109 @@
use cargo_apk::{ApkBuilder, Error};
use cargo_subcommand::Subcommand;
use std::process::Command;
use clap::Parser;

#[derive(Parser)]
struct Cmd {
#[clap(subcommand)]
apk: ApkCmd,
}

#[derive(clap::Subcommand)]
enum ApkCmd {
/// Helps cargo build apks for Android
Apk {
#[clap(subcommand)]
cmd: ApkSubCmd,
},
}

#[derive(Parser)]
struct Args {
#[clap(flatten)]
subcommand_args: cargo_subcommand::Args,
/// Use device with the given serial (see `adb devices`)
#[clap(short, long)]
device: Option<String>,
}

#[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")]
Check {
#[clap(flatten)]
args: Args,
},
/// Compile the current package and create an apk
#[clap(visible_alias = "b")]
Build {
#[clap(flatten)]
args: Args,
},
/// Invoke `cargo` under the detected NDK environment
#[clap(name = "--")]
Ndk {
cargo_cmd: String,
#[clap(flatten)]
args: Args,
},
/// Run a binary or example apk of the local package
#[clap(visible_alias = "r")]
Run {
#[clap(flatten)]
args: Args,
/// Do not print or follow `logcat` after running the app
#[clap(short, long)]
no_logcat: bool,
},
/// Start a gdb session attached to an adb device with symbols loaded
Gdb {
#[clap(flatten)]
args: Args,
},
/// Print the version of cargo-apk
Version,
}

fn main() -> anyhow::Result<()> {
env_logger::init();
let args = std::env::args();
let mut device_serial = None;
let mut no_logcat = false;
let cmd = Subcommand::new(args, "apk", |name, value| match name {
"--device" => {
if let Some(value) = value {
println!("Running on {}", value);
device_serial = Some(value.to_owned());
Ok(true)
} else {
Err(cargo_subcommand::Error::InvalidArgs)
}
}
"--no-logcat" => {
no_logcat = true;
Ok(true)
let Cmd {
apk: ApkCmd::Apk { cmd },
} = Cmd::parse();
match cmd {
ApkSubCmd::Check { args } => {
let cmd = Subcommand::new(args.subcommand_args)?;
let builder = ApkBuilder::from_subcommand(&cmd, args.device)?;
builder.check()?;
}
_ => Ok(false),
})
.map_err(Error::Subcommand)?;

let builder = ApkBuilder::from_subcommand(&cmd, device_serial, no_logcat)?;

match cmd.cmd() {
"check" | "c" => builder.check()?,
"build" | "b" => {
ApkSubCmd::Build { args } => {
let cmd = Subcommand::new(args.subcommand_args)?;
let builder = ApkBuilder::from_subcommand(&cmd, args.device)?;
for artifact in cmd.artifacts() {
builder.build(artifact)?;
}
}
"run" | "r" => {
anyhow::ensure!(cmd.artifacts().len() == 1, Error::invalid_args());
builder.run(&cmd.artifacts()[0])?;
ApkSubCmd::Ndk { cargo_cmd, args } => {
let cmd = Subcommand::new(args.subcommand_args)?;
let builder = ApkBuilder::from_subcommand(&cmd, args.device)?;
builder.default(&cargo_cmd)?;
}
"--" => {
builder.default()?;
ApkSubCmd::Run { args, no_logcat } => {
let cmd = Subcommand::new(args.subcommand_args)?;
let builder = ApkBuilder::from_subcommand(&cmd, args.device)?;
anyhow::ensure!(cmd.artifacts().len() == 1, Error::invalid_args());
builder.run(&cmd.artifacts()[0], no_logcat)?;
}
"gdb" => {
ApkSubCmd::Gdb { args } => {
let cmd = Subcommand::new(args.subcommand_args)?;
let builder = ApkBuilder::from_subcommand(&cmd, args.device)?;
anyhow::ensure!(cmd.artifacts().len() == 1, Error::invalid_args());
builder.gdb(&cmd.artifacts()[0])?;
}
"help" => {
if let Some(arg) = cmd.args().get(0) {
match &**arg {
"build" | "b" | "check" | "c" | "run" | "r" | "test" | "t" | "doc" => {
run_cargo(&cmd)?
}
"gdb" => print_gdb_help(),
_ => print_help(),
}
} else {
print_help();
}
}
"version" => {
ApkSubCmd::Version => {
println!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
}
_ => print_help(),
}

Ok(())
}

fn run_cargo(cmd: &Subcommand) -> Result<(), Error> {
Command::new("cargo")
.arg(cmd.cmd())
.args(cmd.args())
.status()?;
Ok(())
}

fn print_help() {
println!(
r#"cargo-apk
Helps cargo build apk's for android
USAGE:
cargo apk [SUBCOMMAND]
SUBCOMMAND:
check, c Checks that the current package builds without creating an apk
build, b Compiles the current package and creates an apk
run, r Run a binary or example of the local package
gdb Start a gdb session attached to an adb device with symbols loaded
version Print the version of cargo-apk
FLAGS:
--no-logcat Don't print and follow `logcat` after running the application.
OPTIONS:
--device <serial> Use device with the given serial. See `adb devices` for a list of
connected Android devices.
"#
);
}

fn print_gdb_help() {
println!(
r#"cargo-apk gdb
Start a gdb session attached to an adb device with symbols loaded
USAGE:
cargo apk gdb
"#
);
}

0 comments on commit b488fb9

Please sign in to comment.