diff --git a/.cargo/config.toml b/.cargo/config.toml index 95d2a3517..b75130124 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,5 +1,5 @@ [alias] -xtask = "run --manifest-path xtask/Cargo.toml --" +xtask = "run --manifest-path xtask/Cargo.toml" [build] rustflags = [ diff --git a/xtask/Cargo.lock b/xtask/Cargo.lock index fca587e0e..c213ff96b 100644 --- a/xtask/Cargo.lock +++ b/xtask/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "aho-corasick" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" -dependencies = [ - "memchr", -] - [[package]] name = "anyhow" version = "1.0.71" @@ -74,11 +65,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" dependencies = [ - "humantime", - "is-terminal", "log", - "regex", - "termcolor", ] [[package]] @@ -126,12 +113,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - [[package]] name = "id-arena" version = "2.2.1" @@ -158,18 +139,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "is-terminal" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" -dependencies = [ - "hermit-abi", - "io-lifetimes", - "rustix", - "windows-sys 0.48.0", -] - [[package]] name = "itoa" version = "1.0.6" @@ -200,12 +169,6 @@ version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - [[package]] name = "pico-args" version = "0.5.0" @@ -239,23 +202,6 @@ dependencies = [ "bitflags", ] -[[package]] -name = "regex" -version = "1.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" - [[package]] name = "rustc-demangle" version = "0.1.23" @@ -329,15 +275,6 @@ dependencies = [ "windows-sys 0.45.0", ] -[[package]] -name = "termcolor" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" -dependencies = [ - "winapi-util", -] - [[package]] name = "unicode-ident" version = "1.0.9" @@ -463,37 +400,6 @@ version = "0.77.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fe3d5405e9ea6c1317a656d6e0820912d8b7b3607823a7596117c8f666daf6f" -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - [[package]] name = "windows-sys" version = "0.45.0" diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 44f61320c..0c99c35d9 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -4,14 +4,25 @@ version = "0.1.0" edition = "2021" publish = false +[features] +run-wasm = ["cargo-run-wasm"] + [dependencies] +# The dependencies in this config have no transitive dependencies. anyhow = "1.0.71" -# Current contents filed as a PR here: -# -cargo-run-wasm = { version = "0.3.2", git = "https://github.com/ErichDonGubler/cargo-run-wasm", branch = "expose-args" } -env_logger = "0.10.0" +env_logger = { version = "0.10.0", default-features = false } log = "0.4.18" -pico-args = { version = "0.5.0", features = ["eq-separator", "short-space-opt", "combined-flags"] } +pico-args = { version = "0.5.0", features = [ + "eq-separator", + "short-space-opt", + "combined-flags", +] } xshell = "0.2.3" +# Feature: run-wasm + +# Current contents filed as a PR here: +# +cargo-run-wasm = { version = "0.3.2", git = "https://github.com/ErichDonGubler/cargo-run-wasm", branch = "expose-args", optional = true } + [workspace] diff --git a/xtask/src/cli.rs b/xtask/src/cli.rs index 26831f769..50a79483c 100644 --- a/xtask/src/cli.rs +++ b/xtask/src/cli.rs @@ -15,14 +15,14 @@ Options: -h, --help Print help "; -pub(crate) struct Args { - pub(crate) subcommand: Subcommand, +pub struct Args { + pub subcommand: Subcommand, + pub command_args: Arguments, } impl Args { pub fn parse() -> Self { let mut args = Arguments::from_env(); - log::debug!("parsing args: {args:?}"); if args.contains("--help") { eprint!("{HELP}"); // Emulate Cargo exit status: @@ -30,8 +30,11 @@ impl Args { let cargo_like_exit_code = 101; exit(cargo_like_exit_code); } - match Subcommand::parse(args).map(|subcommand| Self { subcommand }) { - Ok(this) => this, + match Subcommand::parse(&mut args) { + Ok(subcommand) => Self { + subcommand, + command_args: args, + }, Err(e) => { eprintln!("{:?}", anyhow!(e)); exit(1) @@ -40,20 +43,47 @@ impl Args { } } -pub(crate) enum Subcommand { - RunWasm { args: Arguments }, - Test { args: Arguments }, +pub enum Subcommand { + RunWasm, + Test, } impl Subcommand { - fn parse(mut args: Arguments) -> anyhow::Result { + /// Returns the name of the subcommand as a string. + /// + /// Opposite of [`Self::parse`]. + pub fn to_str(&self) -> &'static str { + match self { + Self::RunWasm => "run-wasm", + Self::Test => "test", + } + } + + /// Returns true if all required features are enabled for this subcommand. + pub fn required_features_enabled(&self) -> bool { + match self { + Self::RunWasm => cfg!(feature = "run-wasm"), + Self::Test => true, + } + } + + /// Comma separated list of features required by this subcommand. + pub fn features(&self) -> &'static str { + match self { + Self::RunWasm => "run-wasm", + // We will never ask for the features if required_features_enabled always returns true. + Self::Test => unreachable!(), + } + } + + fn parse(args: &mut Arguments) -> anyhow::Result { let subcmd = args .subcommand() .context("failed to parse subcommand")? .context("no subcommand specified; see `--help` for more details")?; match &*subcmd { - "run-wasm" => Ok(Self::RunWasm { args }), - "test" => Ok(Self::Test { args }), + "run-wasm" => Ok(Self::RunWasm), + "test" => Ok(Self::Test), other => { bail!("unrecognized subcommand {other:?}; see `--help` for more details") } diff --git a/xtask/src/main.rs b/xtask/src/main.rs index cad9aa541..01b9aa933 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,13 +1,12 @@ -use std::process::ExitCode; +use std::process::Command; use anyhow::Context; -use cli::{Args, Subcommand}; -use pico_args::Arguments; +use cli::Args; mod cli; mod test; -fn main() -> ExitCode { +fn main() -> anyhow::Result<()> { env_logger::builder() .filter_level(log::LevelFilter::Info) .parse_default_env() @@ -16,27 +15,48 @@ fn main() -> ExitCode { let args = Args::parse(); - match run(args) { - Ok(()) => ExitCode::SUCCESS, - Err(e) => { - log::error!("{e:?}"); - ExitCode::FAILURE + if !args.subcommand.required_features_enabled() { + let features = args.subcommand.features(); + log::info!( + "Required features \"{features}\" are not enabled, recursing with features enabled" + ); + + let subcommand_args = args.command_args.finish(); + let iter = subcommand_args + .iter() + .map(|os| os.as_os_str().to_str().unwrap()); + + let status = Command::new("cargo") + .args(["xtask", "--features", features, args.subcommand.to_str()]) + .args(iter) + .status() + .context("Failed to execute recursive cargo xtask")?; + + if status.success() { + return Ok(()); + } else { + return Err(anyhow::anyhow!("subcommand failed")); } } + + run(args) } -fn run(args: Args) -> anyhow::Result<()> { - let Args { subcommand } = args; - match subcommand { - Subcommand::RunWasm { mut args } => { +#[allow(unused_mut, unreachable_patterns)] +fn run(mut args: Args) -> anyhow::Result<()> { + match args.subcommand { + #[cfg(feature = "run-wasm")] + cli::Subcommand::RunWasm => { + log::info!("Running wasm example"); // Use top-level Cargo.toml instead of xtask/Cargo.toml by default let manifest_path = args + .command_args .value_from_str("--manifest-path") .unwrap_or_else(|_| "../Cargo.toml".to_string()); - let mut arg_vec = args.finish(); + let mut arg_vec = args.command_args.finish(); arg_vec.push("--manifest-path".into()); arg_vec.push(manifest_path.into()); - let args = Arguments::from_vec(arg_vec); + let args = pico_args::Arguments::from_vec(arg_vec); cargo_run_wasm::run_wasm_with_css_and_args( "body { margin: 0px; }", @@ -46,6 +66,7 @@ fn run(args: Args) -> anyhow::Result<()> { ); Ok(()) } - Subcommand::Test { args } => test::run_tests(args), + cli::Subcommand::Test => test::run_tests(args.command_args), + _ => unreachable!(), } }