diff options
| author | Henrik Tjäder <henrik@tjaders.com> | 2023-02-28 23:55:02 +0100 |
|---|---|---|
| committer | Henrik Tjäder <henrik@tjaders.com> | 2023-03-01 00:35:27 +0100 |
| commit | a575266ec2da56fb202de35948650c7f11a2909d (patch) | |
| tree | e045e59180d872902661911f97f0eaa2fbc86508 /xtask/src/main.rs | |
| parent | 14457da4f831c57e7a2b1c54e1c37adb8354c8d5 (diff) | |
xtask: Add tests, clean a bit
Diffstat (limited to 'xtask/src/main.rs')
| -rw-r--r-- | xtask/src/main.rs | 307 |
1 files changed, 212 insertions, 95 deletions
diff --git a/xtask/src/main.rs b/xtask/src/main.rs index d881224..2daddaa 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -17,7 +17,6 @@ use std::{ }; use env_logger::Env; -use exitcode; use log::{debug, error, info, log_enabled, trace, Level}; use crate::{ @@ -34,6 +33,88 @@ const ARMV8MMAIN: &str = "thumbv8m.main-none-eabi"; const DEFAULT_FEATURES: &str = "test-critical-section"; +#[derive(clap::ValueEnum, Copy, Clone, Debug)] +pub enum Package { + Rtic, + RticArbiter, + RticChannel, + RticCommon, + RticMacros, + RticMonotonics, + RticTime, +} + +impl fmt::Display for Package { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.to_string()) + } +} + +impl Package { + fn to_string(&self) -> &str { + match self { + Package::Rtic => "rtic", + Package::RticArbiter => "rtic-arbiter", + Package::RticChannel => "rtic-channel", + Package::RticCommon => "rtic-common", + Package::RticMacros => "rtic-macros", + Package::RticMonotonics => "rtic-monotonics", + Package::RticTime => "rtic-time", + } + } +} + +struct TestMetadata {} + +impl TestMetadata { + fn match_package(package: Package, backend: Backends) -> CargoCommand<'static> { + match package { + Package::Rtic => { + let features = Some(format!( + "{},{}", + DEFAULT_FEATURES, + backend.to_rtic_feature(), + )); + CargoCommand::Test { + package: Some(package), + features, + test: Some("ui".to_owned()), + } + } + Package::RticMacros => CargoCommand::Test { + package: Some(package), + features: Some(backend.to_rtic_macros_feature().to_owned()), + test: None, + }, + Package::RticArbiter => CargoCommand::Test { + package: Some(package), + features: Some("testing".to_owned()), + test: None, + }, + Package::RticChannel => CargoCommand::Test { + package: Some(package), + features: Some("testing".to_owned()), + test: None, + }, + Package::RticCommon => CargoCommand::Test { + package: Some(package), + features: Some("testing".to_owned()), + test: None, + }, + Package::RticMonotonics => CargoCommand::Test { + package: Some(package), + features: None, + test: Some("tests".to_owned()), + }, + Package::RticTime => CargoCommand::Test { + package: Some(package), + features: None, + test: None, + }, + } + } +} + #[derive(clap::ValueEnum, Copy, Clone, Default, Debug)] enum Backends { Thumbv6, @@ -61,6 +142,14 @@ impl Backends { Backends::Thumbv8Main => "thumbv8main-backend", } } + fn to_rtic_macros_feature(&self) -> &str { + match self { + Backends::Thumbv6 => "cortex-m-source-masking", + Backends::Thumbv7 => "cortex-m-basepri", + Backends::Thumbv8Base => "cortex-m-source-masking", + Backends::Thumbv8Main => "cortex-m-basepri", + } + } } #[derive(Copy, Clone, Default, Debug)] @@ -108,19 +197,19 @@ struct Cli { #[derive(Debug, Subcommand)] enum Commands { /// Check formatting - FormatCheck(Package), + FormatCheck(PackageOpt), /// Format code - Format(Package), + Format(PackageOpt), /// Run clippy - Clippy(Package), + Clippy(PackageOpt), /// Check all packages - Check(Package), + Check(PackageOpt), /// Build all packages - Build(Package), + Build(PackageOpt), /// Check all examples ExampleCheck, @@ -155,17 +244,20 @@ enum Commands { /// Build docs Doc, + /// Run tests + Test(PackageOpt), + /// Build books with mdbook Book, } #[derive(Args, Debug)] /// Restrict to package, or run on whole workspace -struct Package { +struct PackageOpt { /// For which package/workspace member to operate /// /// If omitted, work on all - package: Option<String>, + package: Option<Package>, } #[derive(Args, Debug)] @@ -379,14 +471,14 @@ fn main() -> anyhow::Result<()> { &examples_to_run, )?; } - Commands::Size(arguments) => { + Commands::Size(args) => { // x86_64 target not valid info!("Measuring for backend: {backend:?}"); build_and_check_size( &cargologlevel, backend, &examples_to_run, - &arguments.sizearguments, + &args.sizearguments, )?; } Commands::Qemu(args) | Commands::Run(args) => { @@ -403,6 +495,10 @@ fn main() -> anyhow::Result<()> { info!("Running cargo doc on backend: {backend:?}"); cargo_doc(&cargologlevel, backend)?; } + Commands::Test(args) => { + info!("Running cargo test on backend: {backend:?}"); + cargo_test(&args, backend)?; + } Commands::Book => { info!("Running mdbook build"); cargo_book(&cargologlevel)?; @@ -415,30 +511,22 @@ fn main() -> anyhow::Result<()> { fn cargo( operation: BuildOrCheck, cargoarg: &Option<&str>, - package: &Package, + package: &PackageOpt, backend: Backends, ) -> anyhow::Result<()> { - // rtic crate has features which needs special handling - let rtic_features = &format!("{},{}", DEFAULT_FEATURES, backend.to_rtic_feature()); - let features: Option<&str>; - let packages = package_filter(package); - features = if packages.contains(&"rtic".to_owned()) { - Some(&rtic_features) - } else { - None - }; + let features = package_feature_extractor(package, backend); let command = match operation { BuildOrCheck::Check => CargoCommand::Check { cargoarg, - package: packages, + package: package.package, target: backend.to_target(), features, mode: BuildMode::Release, }, BuildOrCheck::Build => CargoCommand::Build { cargoarg, - package: packages, + package: package.package, target: backend.to_target(), features, mode: BuildMode::Release, @@ -454,10 +542,13 @@ fn cargo_example( backend: Backends, examples: &[String], ) -> anyhow::Result<()> { - let s = format!("{},{}", DEFAULT_FEATURES, backend.to_rtic_feature()); - let features: Option<&str> = Some(&s); - examples.into_par_iter().for_each(|example| { + let features = Some(format!( + "{},{}", + DEFAULT_FEATURES, + backend.to_rtic_feature() + )); + let command = match operation { BuildOrCheck::Check => CargoCommand::ExampleCheck { cargoarg, @@ -485,47 +576,31 @@ fn cargo_example( fn cargo_clippy( cargoarg: &Option<&str>, - package: &Package, + package: &PackageOpt, backend: Backends, ) -> anyhow::Result<()> { - let packages_to_check = package_filter(package); - if packages_to_check.contains(&"rtic".to_owned()) { - // rtic crate has features which needs special handling - let s = format!("{},{}", DEFAULT_FEATURES, backend.to_rtic_feature()); - let features: Option<&str> = Some(&s); - - command_parser( - &CargoCommand::Clippy { - cargoarg, - package: package_filter(package), - target: backend.to_target(), - features, - }, - false, - )?; - } else { - command_parser( - &CargoCommand::Clippy { - cargoarg, - package: package_filter(package), - target: backend.to_target(), - features: None, - }, - false, - )?; - } + let features = package_feature_extractor(package, backend); + command_parser( + &CargoCommand::Clippy { + cargoarg, + package: package.package, + target: backend.to_target(), + features, + }, + false, + )?; Ok(()) } fn cargo_format( cargoarg: &Option<&str>, - package: &Package, + package: &PackageOpt, check_only: bool, ) -> anyhow::Result<()> { command_parser( &CargoCommand::Format { cargoarg, - package: package_filter(package), + package: package.package, check_only, }, false, @@ -534,13 +609,55 @@ fn cargo_format( } fn cargo_doc(cargoarg: &Option<&str>, backend: Backends) -> anyhow::Result<()> { - let s = format!("{}", backend.to_rtic_feature()); - let features: Option<&str> = Some(&s); + let features = Some(format!( + "{},{}", + DEFAULT_FEATURES, + backend.to_rtic_feature() + )); command_parser(&CargoCommand::Doc { cargoarg, features }, false)?; Ok(()) } +fn cargo_test(package: &PackageOpt, backend: Backends) -> anyhow::Result<()> { + if let Some(package) = package.package { + let cmd = match package { + Package::Rtic => TestMetadata::match_package(package, backend), + Package::RticArbiter => TestMetadata::match_package(package, backend), + Package::RticChannel => TestMetadata::match_package(package, backend), + Package::RticCommon => TestMetadata::match_package(package, backend), + Package::RticMacros => TestMetadata::match_package(package, backend), + Package::RticMonotonics => TestMetadata::match_package(package, backend), + Package::RticTime => TestMetadata::match_package(package, backend), + }; + command_parser(&cmd, false)?; + } else { + // Iterate over all workspace packages + for package in [ + Package::Rtic, + Package::RticArbiter, + Package::RticChannel, + Package::RticCommon, + Package::RticMacros, + Package::RticMonotonics, + Package::RticTime, + ] { + let mut error_messages = vec![]; + let cmd = &TestMetadata::match_package(package, backend); + if let Err(err) = command_parser(&cmd, false) { + error_messages.push(err); + } + + if !error_messages.is_empty() { + for err in error_messages { + error!("{err}"); + } + } + } + } + Ok(()) +} + fn cargo_book(cargoarg: &Option<&str>) -> anyhow::Result<()> { command_parser( &CargoCommand::Book { @@ -557,15 +674,16 @@ fn run_test( examples: &[String], overwrite: bool, ) -> anyhow::Result<()> { - let s = format!("{},{}", DEFAULT_FEATURES, backend.to_rtic_feature()); - let features: Option<&str> = Some(&s); - examples.into_par_iter().for_each(|example| { let cmd = CargoCommand::ExampleBuild { cargoarg: &Some("--quiet"), example, target: backend.to_target(), - features, + features: Some(format!( + "{},{}", + DEFAULT_FEATURES, + backend.to_rtic_feature() + )), mode: BuildMode::Release, }; if let Err(err) = command_parser(&cmd, false) { @@ -576,7 +694,11 @@ fn run_test( cargoarg, example, target: backend.to_target(), - features, + features: Some(format!( + "{},{}", + DEFAULT_FEATURES, + backend.to_rtic_feature() + )), mode: BuildMode::Release, }; @@ -594,16 +716,17 @@ fn build_and_check_size( examples: &[String], size_arguments: &Option<Sizearguments>, ) -> anyhow::Result<()> { - let s = format!("{},{}", DEFAULT_FEATURES, backend.to_rtic_feature()); - let features: Option<&str> = Some(&s); - examples.into_par_iter().for_each(|example| { // Make sure the requested example(s) are built let cmd = CargoCommand::ExampleBuild { cargoarg: &Some("--quiet"), example, target: backend.to_target(), - features, + features: Some(format!( + "{},{}", + DEFAULT_FEATURES, + backend.to_rtic_feature() + )), mode: BuildMode::Release, }; if let Err(err) = command_parser(&cmd, false) { @@ -614,7 +737,11 @@ fn build_and_check_size( cargoarg, example, target: backend.to_target(), - features, + features: Some(format!( + "{},{}", + DEFAULT_FEATURES, + backend.to_rtic_feature() + )), mode: BuildMode::Release, arguments: size_arguments.clone(), }; @@ -626,38 +753,27 @@ fn build_and_check_size( Ok(()) } -fn package_filter(package: &Package) -> Vec<String> { - // TODO Parse Cargo.toml workspace definition instead? - let packages: Vec<String> = [ - "rtic".to_owned(), - "rtic-arbiter".to_owned(), - "rtic-channel".to_owned(), - "rtic-common".to_owned(), - "rtic-macros".to_owned(), - "rtic-monotonics".to_owned(), - "rtic-time".to_owned(), - ] - .to_vec(); - - let package_selected; - - if let Some(package) = package.package.clone() { - if packages.contains(&package) { - debug!("\nTesting package: {package}"); - // If we managed to filter, set the packages to test to only this one - package_selected = vec![package] - } else { - error!( - "\nThe package you specified is not available. Available packages are:\ - \n{packages:#?}\n\ - By default all packages are tested.", - ); - process::exit(exitcode::USAGE); +/// 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(package: &PackageOpt, backend: Backends) -> Option<String> { + let default_features = Some(format!( + "{},{}", + DEFAULT_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 { - package_selected = packages; + default_features } - package_selected } // run example binary `example` @@ -704,6 +820,7 @@ fn command_parser(command: &CargoCommand, overwrite: bool) -> anyhow::Result<()> | CargoCommand::Build { .. } | CargoCommand::Clippy { .. } | CargoCommand::Doc { .. } + | CargoCommand::Test { .. } | CargoCommand::Book { .. } | CargoCommand::ExampleSize { .. } => { let cargo_result = run_command(command)?; |
