diff --git a/xtask/src/argument_parsing.rs b/xtask/src/argument_parsing.rs index f643cbb610..7284fc553e 100644 --- a/xtask/src/argument_parsing.rs +++ b/xtask/src/argument_parsing.rs @@ -29,6 +29,30 @@ impl Package { Package::RticTime => "rtic-time", } } + + pub fn all() -> Vec { + vec![ + Self::Rtic, + Self::RticCommon, + Self::RticMacros, + Self::RticMonotonics, + Self::RticSync, + Self::RticTime, + ] + } + + /// Get the features needed given the selected package + /// + /// Without package specified the features for RTIC are required + /// With only a single package which is not RTIC, no special + /// features are needed + pub fn extract_features(&self, target: Target, backend: Backends) -> Option { + match self { + Package::Rtic => Some(target.and_features(backend.to_rtic_feature())), + Package::RticMacros => Some(backend.to_rtic_macros_feature().to_owned()), + _ => None, + } + } } pub struct TestMetadata {} @@ -247,7 +271,16 @@ pub struct PackageOpt { /// For which package/workspace member to operate /// /// If omitted, work on all - pub package: Option, + package: Option, +} + +impl PackageOpt { + pub fn packages(&self) -> impl Iterator { + self.package + .map(|p| vec![p]) + .unwrap_or(Package::all()) + .into_iter() + } } #[derive(Args, Debug, Clone)] diff --git a/xtask/src/cargo_commands.rs b/xtask/src/cargo_commands.rs index af6114187f..2a15b3c163 100644 --- a/xtask/src/cargo_commands.rs +++ b/xtask/src/cargo_commands.rs @@ -1,9 +1,7 @@ use crate::{ - argument_parsing::{ - Backends, BuildOrCheck, ExtraArguments, Globals, Package, PackageOpt, TestMetadata, - }, + argument_parsing::{Backends, BuildOrCheck, ExtraArguments, Globals, PackageOpt, TestMetadata}, command::{BuildMode, CargoCommand}, - command_parser, package_feature_extractor, + command_parser, }; use log::error; use rayon::prelude::*; @@ -16,26 +14,42 @@ pub fn cargo( package: &PackageOpt, backend: Backends, ) -> anyhow::Result<()> { - let target = backend.to_target(); - let features = package_feature_extractor(target, package, backend); + package.packages().for_each(|package| { + let target = backend.to_target(); + + let features = package.extract_features(target, backend); + + match operation { + BuildOrCheck::Check => { + log::debug!(target: "xtask::command", "Checking package: {package}") + } + BuildOrCheck::Build => { + log::debug!(target: "xtask::command", "Building package: {package}") + } + } + + let command = match operation { + BuildOrCheck::Check => CargoCommand::Check { + cargoarg, + package: Some(package), + target, + features, + mode: BuildMode::Release, + }, + BuildOrCheck::Build => CargoCommand::Build { + cargoarg, + package: Some(package), + target, + features, + mode: BuildMode::Release, + }, + }; + let res = command_parser(globals, &command, false); + if let Err(e) = res { + error!("{e}"); + } + }); - let command = match operation { - BuildOrCheck::Check => CargoCommand::Check { - cargoarg, - package: package.package, - target, - features, - mode: BuildMode::Release, - }, - BuildOrCheck::Build => CargoCommand::Build { - cargoarg, - package: package.package, - target, - features, - mode: BuildMode::Release, - }, - }; - command_parser(globals, &command, false)?; Ok(()) } @@ -84,18 +98,26 @@ pub fn cargo_clippy( package: &PackageOpt, backend: Backends, ) -> anyhow::Result<()> { - let target = backend.to_target(); - let features = package_feature_extractor(target, package, backend); - command_parser( - globals, - &CargoCommand::Clippy { - cargoarg, - package: package.package, - target, - features, - }, - false, - )?; + package.packages().for_each(|p| { + let target = backend.to_target(); + let features = p.extract_features(target, backend); + + let res = command_parser( + globals, + &CargoCommand::Clippy { + cargoarg, + package: Some(p), + target, + features, + }, + false, + ); + + if let Err(e) = res { + error!("{e}") + } + }); + Ok(()) } @@ -106,15 +128,22 @@ pub fn cargo_format( package: &PackageOpt, check_only: bool, ) -> anyhow::Result<()> { - command_parser( - globals, - &CargoCommand::Format { - cargoarg, - package: package.package, - check_only, - }, - false, - )?; + package.packages().for_each(|p| { + let res = command_parser( + globals, + &CargoCommand::Format { + cargoarg, + package: Some(p), + check_only, + }, + false, + ); + + if let Err(e) = res { + error!("{e}") + } + }); + Ok(()) } @@ -147,32 +176,13 @@ pub fn cargo_test( package: &PackageOpt, backend: Backends, ) -> anyhow::Result<()> { - if let Some(package) = package.package { - let cmd = TestMetadata::match_package(package, backend); - command_parser(globals, &cmd, false)?; - } else { - // Iterate over all workspace packages - for package in [ - Package::Rtic, - Package::RticCommon, - Package::RticMacros, - Package::RticMonotonics, - Package::RticSync, - Package::RticTime, - ] { - let mut error_messages = vec![]; - let cmd = &TestMetadata::match_package(package, backend); - if let Err(err) = command_parser(globals, cmd, false) { - error_messages.push(err); - } - - if !error_messages.is_empty() { - for err in error_messages { - error!("{err}"); - } - } + package.packages().for_each(|p| { + let cmd = &TestMetadata::match_package(p, backend); + if let Err(err) = command_parser(globals, cmd, false) { + error!("{err}") } - } + }); + Ok(()) } @@ -209,6 +219,7 @@ pub fn run_test( features: features.clone(), mode: BuildMode::Release, }; + if let Err(err) = command_parser(globals, &cmd, false) { error!("{err}"); } diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 8f6a556971..f2d01809ba 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -24,7 +24,7 @@ use env_logger::Env; use log::{debug, error, info, log_enabled, trace, Level}; use crate::{ - argument_parsing::{Backends, BuildOrCheck, Cli, Commands, PackageOpt}, + argument_parsing::{Backends, BuildOrCheck, Cli, Commands}, build::init_build_dir, cargo_commands::{ build_and_check_size, cargo, cargo_book, cargo_clippy, cargo_doc, cargo_example, @@ -299,30 +299,6 @@ fn main() -> anyhow::Result<()> { Ok(()) } -/// Get the features needed given the selected package -/// -/// Without package specified the features for RTIC are required -/// With only a single package which is not RTIC, no special -/// features are needed -fn package_feature_extractor( - target: Target, - package: &PackageOpt, - backend: Backends, -) -> Option { - let default_features = Some(target.and_features(backend.to_rtic_feature())); - - if let Some(package) = package.package { - debug!("\nTesting package: {package}"); - match package { - Package::Rtic => default_features, - Package::RticMacros => Some(backend.to_rtic_macros_feature().to_owned()), - _ => None, - } - } else { - default_features - } -} - // run example binary `example` fn command_parser(glob: &Globals, command: &CargoCommand, overwrite: bool) -> anyhow::Result<()> { let output_mode = if glob.stderr_inherited {