Browse Source

Upgrade to clap4, add extra args and help strings

pull/26/head
Ian Chamberlain 2 years ago
parent
commit
cef69644e6
No known key found for this signature in database
GPG Key ID: AE5484D09405AA60
  1. 4
      Cargo.toml
  2. 133
      src/command.rs
  3. 49
      src/main.rs

4
Cargo.toml

@ -11,7 +11,7 @@ edition = "2021"
cargo_metadata = "0.14.0" cargo_metadata = "0.14.0"
rustc_version = "0.4.0" rustc_version = "0.4.0"
semver = "1.0.10" semver = "1.0.10"
serde = {version = "1.0.139", features = ['derive']} serde = { version = "1.0.139", features = ['derive'] }
tee = "0.1.0" tee = "0.1.0"
toml = "0.5.6" toml = "0.5.6"
clap = { version = "3.2.12", features = ["derive"]} clap = { version = "4.0.15", features = ["derive", "wrap_help"] }

133
src/command.rs

@ -1,36 +1,123 @@
use clap::{AppSettings, Args, Parser, ValueEnum}; // TODO: docstrings for everything!!!
#[derive(Parser)] use clap::{Args, Parser, Subcommand};
#[clap(name = "cargo")]
#[clap(bin_name = "cargo")] #[derive(Parser, Debug)]
pub enum Cargo { #[command(name = "cargo")]
#[clap(name = "3ds")] #[command(bin_name = "cargo")]
Input(Input), pub enum Command {
#[command(name = "3ds")]
Root(Root),
} }
#[derive(Args)] #[derive(Args, Debug)]
#[clap(about)] #[command(version, about)]
#[clap(global_setting(AppSettings::AllowLeadingHyphen))] pub struct Root {
pub struct Input { /// The cargo command to run. This command will be forwarded to the real
#[clap(value_enum)] /// `cargo` with the appropriate arguments for a 3DS executable.
#[command(subcommand)]
pub cmd: CargoCommand, pub cmd: CargoCommand,
pub cargo_opts: Vec<String>,
/// Don't actually run any commands, just echo them to the console.
/// This is mostly intended for testing.
#[arg(hide = true)]
pub dry_run: bool,
/// Pass additional options through to the `cargo` command.
///
/// To pass flags that start with `-`, you must use `--` to separate `cargo 3ds`
/// options from cargo options. All args after `--` will be passed through
/// to cargo unmodified.
///
/// If one of the arguments is itself `--`, the args following that will be
/// considered as args to pass to the executable, rather than to `cargo`
/// (only works for the `run` or `test` commands). For example, if you want
/// to pass some args to the executable directly it might look like this:
///
/// > cargo 3ds run -- -- arg1 arg2
#[arg(trailing_var_arg = true)]
#[arg(global = true)]
cargo_options: Vec<String>,
} }
#[derive(ValueEnum, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] #[derive(Subcommand, Debug)]
pub enum CargoCommand { pub enum CargoCommand {
/// Builds an executable suitable to run on a 3DS (3dsx).
Build, Build,
Run, /// Equivalent to `cargo check`.
Test,
Check, Check,
/// Equivalent to `cargo clippy`.
Clippy, Clippy,
/// Equivalent to `cargo doc`.
Doc,
/// Builds an executable and sends it to a device with `3dslink`.
Run(Run),
/// Builds a test executable and sends it to a device with `3dslink`.
///
/// This can be used with `--test` for integration tests, or `--lib` for
/// unit tests (which require a custom test runner).
Test(Test),
// TODO: this doesn't seem to work for some reason...
#[command(external_subcommand)]
Other(Vec<String>),
} }
impl CargoCommand { #[derive(Args, Debug)]
pub fn should_build_3dsx(&self) -> bool { pub struct Test {
matches!( /// If set, the built executable will not be sent to the device to run it.
self, #[arg(long)]
CargoCommand::Build | CargoCommand::Run | CargoCommand::Test pub no_run: bool,
) #[command(flatten)]
pub run_args: Run,
}
#[derive(Args, Debug)]
pub struct Run {
/// Specify the IP address of the device to send the executable to.
///
/// Corresponds to 3dslink's `--address` arg, which defaults to automatically
/// finding the device.
#[arg(long, short = 'a')]
pub address: Option<String>,
/// Set the 0th argument of the executable when running it. Corresponds to
/// 3dslink's `--argv0` argument.
#[arg(long, short = '0')]
pub argv0: Option<String>,
/// Start the 3dslink server after sending the executable. Corresponds to
/// 3dslink's `--server` argument.
#[arg(long, short = 's')]
pub server: bool,
/// Set the number of tries when connecting to the device to send the executable.
/// Corresponds to 3dslink's `--retries` argument.
// Can't use `short = 'r'` because that would conflict with cargo's `--release/-r`
#[arg(long)]
pub retries: Option<usize>,
}
impl Root {
/// Get the args to be passed to the executable itself (not `cargo`).
pub fn cargo_options(&self) -> &[String] {
self.split_args().0
}
/// Get the args to be passed to the executable itself (not `cargo`).
pub fn executable_args(&self) -> &[String] {
self.split_args().1
}
fn split_args(&self) -> (&[String], &[String]) {
if let Some(split) = self.cargo_options.iter().position(|arg| arg == "--") {
let split = if &self.cargo_options[split] == "--" {
split + 1
} else {
split
};
self.cargo_options.split_at(split)
} else {
(&self.cargo_options[..], &[])
}
} }
} }

49
src/main.rs

@ -1,3 +1,4 @@
use cargo_3ds::cmd_clap4::Command;
use cargo_3ds::command::Cargo; use cargo_3ds::command::Cargo;
use cargo_3ds::{ use cargo_3ds::{
build_3dsx, build_elf, build_smdh, check_rust_version, get_message_format, get_metadata, build_3dsx, build_elf, build_smdh, check_rust_version, get_message_format, get_metadata,
@ -7,34 +8,40 @@ use clap::Parser;
use std::process; use std::process;
fn main() { fn main() {
check_rust_version(); let Command::Root(cmd) = cargo_3ds::cmd_clap4::Command::parse();
let Cargo::Input(mut input) = Cargo::parse(); dbg!(&cmd);
dbg!(cmd.cargo_options());
dbg!(cmd.executable_args());
let should_link = get_should_link(&mut input); // check_rust_version();
let message_format = get_message_format(&mut input);
let (status, messages) = build_elf(input.cmd, &message_format, &input.cargo_opts); // let Cargo::Input(mut input) = Cargo::parse();
if !status.success() { // let should_link = get_should_link(&mut input);
process::exit(status.code().unwrap_or(1)); // let message_format = get_message_format(&mut input);
}
if !input.cmd.should_build_3dsx() { // let (status, messages) = build_elf(input.cmd, &message_format, &input.cargo_opts);
return;
}
eprintln!("Getting metadata"); // if !status.success() {
let app_conf = get_metadata(&messages); // process::exit(status.code().unwrap_or(1));
// }
eprintln!("Building smdh:{}", app_conf.path_smdh().display()); // if !input.cmd.should_build_3dsx() {
build_smdh(&app_conf); // return;
// }
eprintln!("Building 3dsx: {}", app_conf.path_3dsx().display()); // eprintln!("Getting metadata");
build_3dsx(&app_conf); // let app_conf = get_metadata(&messages);
if should_link { // eprintln!("Building smdh:{}", app_conf.path_smdh().display());
eprintln!("Running 3dslink"); // build_smdh(&app_conf);
link(&app_conf);
} // eprintln!("Building 3dsx: {}", app_conf.path_3dsx().display());
// build_3dsx(&app_conf);
// if should_link {
// eprintln!("Running 3dslink");
// link(&app_conf);
// }
} }

Loading…
Cancel
Save