diff options
| author | datdenkikniet <jcdra1@gmail.com> | 2023-04-16 13:22:10 +0200 |
|---|---|---|
| committer | datdenkikniet <jcdra1@gmail.com> | 2023-04-16 13:22:10 +0200 |
| commit | bc92e43b113dae2a34db6b10812d84227ac5a6d6 (patch) | |
| tree | a08dab3cb348727e69870da8a93621b3cb1c2424 /xtask/src/run | |
| parent | 85e2cd6d4b1ac801dbbce2295a6617a56f9ea5a0 (diff) | |
Rename + better printout
Diffstat (limited to 'xtask/src/run')
| -rw-r--r-- | xtask/src/run/mod.rs | 499 |
1 files changed, 0 insertions, 499 deletions
diff --git a/xtask/src/run/mod.rs b/xtask/src/run/mod.rs deleted file mode 100644 index 74179c5..0000000 --- a/xtask/src/run/mod.rs +++ /dev/null @@ -1,499 +0,0 @@ -use std::{ - fs::File, - io::Write, - path::PathBuf, - process::{Command, Stdio}, -}; - -mod results; -pub use results::handle_results; - -mod data; -use data::*; - -mod iter; -use iter::{into_iter, CoalescingRunner}; - -use crate::{ - argument_parsing::{Backends, BuildOrCheck, ExtraArguments, Globals, PackageOpt, TestMetadata}, - cargo_command::{BuildMode, CargoCommand}, -}; - -use log::{error, info}; - -#[cfg(feature = "rayon")] -use rayon::prelude::*; - -fn run_and_convert<'a>( - (global, command, overwrite): (&Globals, CargoCommand<'a>, bool), -) -> FinalRunResult<'a> { - // Run the command - let result = command_parser(global, &command, overwrite); - - let output = match result { - // If running the command succeeded without looking at any of the results, - // log the data and see if the actual execution was succesfull too. - Ok(result) => { - if result.exit_status.success() { - FinalRunResult::Success(command, result) - } else { - FinalRunResult::Failed(command, result) - } - } - // If it didn't and some IO error occured, just panic - Err(e) => FinalRunResult::CommandError(command, e), - }; - - log::trace!("Final result: {output:?}"); - - output -} - -// run example binary `example` -fn command_parser( - glob: &Globals, - command: &CargoCommand, - overwrite: bool, -) -> anyhow::Result<RunResult> { - let output_mode = if glob.stderr_inherited { - OutputMode::Inherited - } else { - OutputMode::PipedAndCollected - }; - - match *command { - CargoCommand::Qemu { example, .. } | CargoCommand::Run { example, .. } => { - /// Check if `run` was successful. - /// returns Ok in case the run went as expected, - /// Err otherwise - pub fn run_successful( - run: &RunResult, - expected_output_file: &str, - ) -> Result<(), TestRunError> { - let file = expected_output_file.to_string(); - - let expected_output = std::fs::read(expected_output_file) - .map(|d| { - String::from_utf8(d) - .map_err(|_| TestRunError::FileError { file: file.clone() }) - }) - .map_err(|_| TestRunError::FileError { file })??; - - let res = if expected_output != run.stdout { - Err(TestRunError::FileCmpError { - expected: expected_output.clone(), - got: run.stdout.clone(), - }) - } else if !run.exit_status.success() { - Err(TestRunError::CommandError(run.clone())) - } else { - Ok(()) - }; - - if res.is_ok() { - log::info!("✅ Success."); - } else { - log::error!("❌ Command failed. Run to completion for the summary."); - } - - res - } - - let run_file = format!("{example}.run"); - let expected_output_file = ["rtic", "ci", "expected", &run_file] - .iter() - .collect::<PathBuf>() - .into_os_string() - .into_string() - .map_err(TestRunError::PathConversionError)?; - - // cargo run <..> - let cargo_run_result = run_command(command, output_mode, false)?; - - // Create a file for the expected output if it does not exist or mismatches - if overwrite { - let result = run_successful(&cargo_run_result, &expected_output_file); - if let Err(e) = result { - // FileError means the file did not exist or was unreadable - error!("Error: {e}"); - let mut file_handle = File::create(&expected_output_file).map_err(|_| { - TestRunError::FileError { - file: expected_output_file.clone(), - } - })?; - info!("Flag --overwrite-expected enabled"); - info!("Creating/updating file: {expected_output_file}"); - file_handle.write_all(cargo_run_result.stdout.as_bytes())?; - }; - } else { - run_successful(&cargo_run_result, &expected_output_file)?; - }; - - Ok(cargo_run_result) - } - CargoCommand::Format { .. } - | CargoCommand::ExampleCheck { .. } - | CargoCommand::ExampleBuild { .. } - | CargoCommand::Check { .. } - | CargoCommand::Build { .. } - | CargoCommand::Clippy { .. } - | CargoCommand::Doc { .. } - | CargoCommand::Test { .. } - | CargoCommand::Book { .. } - | CargoCommand::ExampleSize { .. } => { - let cargo_result = run_command(command, output_mode, true)?; - Ok(cargo_result) - } - } -} - -/// Cargo command to either build or check -pub fn cargo<'c>( - globals: &Globals, - operation: BuildOrCheck, - cargoarg: &'c Option<&'c str>, - package: &'c PackageOpt, - backend: Backends, -) -> Vec<FinalRunResult<'c>> { - let runner = package - .packages() - .flat_map(|package| { - let target = backend.to_target(); - let features = package.features(target, backend, globals.partial); - into_iter(features).map(move |f| (package, target, f)) - }) - .map(move |(package, target, features)| { - let target = target.into(); - let command = match operation { - BuildOrCheck::Check => CargoCommand::Check { - cargoarg, - package: Some(package.name()), - target, - features, - mode: BuildMode::Release, - dir: None, - deny_warnings: globals.deny_warnings, - }, - BuildOrCheck::Build => CargoCommand::Build { - cargoarg, - package: Some(package.name()), - target, - features, - mode: BuildMode::Release, - dir: None, - deny_warnings: globals.deny_warnings, - }, - }; - - (globals, command, false) - }); - - runner.run_and_coalesce() -} - -/// Cargo command to build a usage example. -/// -/// The usage examples are in examples/ -pub fn cargo_usage_example( - globals: &Globals, - operation: BuildOrCheck, - usage_examples: Vec<String>, -) -> Vec<FinalRunResult<'_>> { - into_iter(&usage_examples) - .map(|example| { - let path = format!("examples/{example}"); - - let command = match operation { - BuildOrCheck::Check => CargoCommand::Check { - cargoarg: &None, - mode: BuildMode::Release, - dir: Some(path.into()), - package: None, - target: None, - features: None, - deny_warnings: globals.deny_warnings, - }, - BuildOrCheck::Build => CargoCommand::Build { - cargoarg: &None, - package: None, - target: None, - features: None, - mode: BuildMode::Release, - dir: Some(path.into()), - deny_warnings: globals.deny_warnings, - }, - }; - (globals, command, false) - }) - .run_and_coalesce() -} - -/// Cargo command to either build or check all examples -/// -/// The examples are in rtic/examples -pub fn cargo_example<'c>( - globals: &Globals, - operation: BuildOrCheck, - cargoarg: &'c Option<&'c str>, - backend: Backends, - examples: &'c [String], -) -> Vec<FinalRunResult<'c>> { - let runner = into_iter(examples).map(|example| { - let features = Some(backend.to_target().and_features(backend.to_rtic_feature())); - - let command = match operation { - BuildOrCheck::Check => CargoCommand::ExampleCheck { - cargoarg, - example, - target: Some(backend.to_target()), - features, - mode: BuildMode::Release, - deny_warnings: globals.deny_warnings, - }, - BuildOrCheck::Build => CargoCommand::ExampleBuild { - cargoarg, - example, - target: Some(backend.to_target()), - features, - mode: BuildMode::Release, - dir: Some(PathBuf::from("./rtic")), - deny_warnings: globals.deny_warnings, - }, - }; - (globals, command, false) - }); - runner.run_and_coalesce() -} - -/// Run cargo clippy on selected package -pub fn cargo_clippy<'c>( - globals: &Globals, - cargoarg: &'c Option<&'c str>, - package: &'c PackageOpt, - backend: Backends, -) -> Vec<FinalRunResult<'c>> { - let runner = package - .packages() - .flat_map(|package| { - let target = backend.to_target(); - let features = package.features(target, backend, globals.partial); - into_iter(features).map(move |f| (package, target, f)) - }) - .map(move |(package, target, features)| { - let command = CargoCommand::Clippy { - cargoarg, - package: Some(package.name()), - target: target.into(), - features, - deny_warnings: true, - }; - - (globals, command, false) - }); - - runner.run_and_coalesce() -} - -/// Run cargo fmt on selected package -pub fn cargo_format<'c>( - globals: &Globals, - cargoarg: &'c Option<&'c str>, - package: &'c PackageOpt, - check_only: bool, -) -> Vec<FinalRunResult<'c>> { - let runner = package.packages().map(|p| { - ( - globals, - CargoCommand::Format { - cargoarg, - package: Some(p.name()), - check_only, - }, - false, - ) - }); - runner.run_and_coalesce() -} - -/// Run cargo doc -pub fn cargo_doc<'c>( - globals: &Globals, - cargoarg: &'c Option<&'c str>, - backend: Backends, - arguments: &'c Option<ExtraArguments>, -) -> Vec<FinalRunResult<'c>> { - let features = Some(backend.to_target().and_features(backend.to_rtic_feature())); - - let command = CargoCommand::Doc { - cargoarg, - features, - arguments: arguments.clone(), - deny_warnings: true, - }; - - vec![run_and_convert((globals, command, false))] -} - -/// Run cargo test on the selected package or all packages -/// -/// If no package is specified, loop through all packages -pub fn cargo_test<'c>( - globals: &Globals, - package: &'c PackageOpt, - backend: Backends, -) -> Vec<FinalRunResult<'c>> { - package - .packages() - .map(|p| { - let meta = TestMetadata::match_package(globals.deny_warnings, p, backend); - (globals, meta, false) - }) - .run_and_coalesce() -} - -/// Use mdbook to build the book -pub fn cargo_book<'c>( - globals: &Globals, - arguments: &'c Option<ExtraArguments>, -) -> Vec<FinalRunResult<'c>> { - vec![run_and_convert(( - globals, - CargoCommand::Book { - arguments: arguments.clone(), - }, - false, - ))] -} - -/// Run examples -/// -/// Supports updating the expected output via the overwrite argument -pub fn qemu_run_examples<'c>( - globals: &Globals, - cargoarg: &'c Option<&'c str>, - backend: Backends, - examples: &'c [String], - overwrite: bool, -) -> Vec<FinalRunResult<'c>> { - let target = backend.to_target(); - let features = Some(target.and_features(backend.to_rtic_feature())); - - into_iter(examples) - .flat_map(|example| { - let target = target.into(); - let cmd_build = CargoCommand::ExampleBuild { - cargoarg: &None, - example, - target, - features: features.clone(), - mode: BuildMode::Release, - dir: Some(PathBuf::from("./rtic")), - deny_warnings: globals.deny_warnings, - }; - - let cmd_qemu = CargoCommand::Qemu { - cargoarg, - example, - target, - features: features.clone(), - mode: BuildMode::Release, - dir: Some(PathBuf::from("./rtic")), - deny_warnings: globals.deny_warnings, - }; - - into_iter([cmd_build, cmd_qemu]) - }) - .map(|cmd| (globals, cmd, overwrite)) - .run_and_coalesce() -} - -/// Check the binary sizes of examples -pub fn build_and_check_size<'c>( - globals: &Globals, - cargoarg: &'c Option<&'c str>, - backend: Backends, - examples: &'c [String], - arguments: &'c Option<ExtraArguments>, -) -> Vec<FinalRunResult<'c>> { - let target = backend.to_target(); - let features = Some(target.and_features(backend.to_rtic_feature())); - - let runner = into_iter(examples).map(|example| { - let target = target.into(); - - // Make sure the requested example(s) are built - let cmd = CargoCommand::ExampleBuild { - cargoarg: &Some("--quiet"), - example, - target, - features: features.clone(), - mode: BuildMode::Release, - dir: Some(PathBuf::from("./rtic")), - deny_warnings: globals.deny_warnings, - }; - - if let Err(err) = command_parser(globals, &cmd, false) { - error!("{err}"); - } - - let cmd = CargoCommand::ExampleSize { - cargoarg, - example, - target, - features: features.clone(), - mode: BuildMode::Release, - arguments: arguments.clone(), - dir: Some(PathBuf::from("./rtic")), - }; - (globals, cmd, false) - }); - - runner.run_and_coalesce() -} - -fn run_command( - command: &CargoCommand, - stderr_mode: OutputMode, - print_command_success: bool, -) -> anyhow::Result<RunResult> { - log::info!("👟 {command}"); - - let mut process = Command::new(command.executable()); - - process - .args(command.args()) - .stdout(Stdio::piped()) - .stderr(stderr_mode); - - if let Some(dir) = command.chdir() { - process.current_dir(dir.canonicalize()?); - } - - if let Some((k, v)) = command.extra_env() { - process.env(k, v); - } - - let result = process.output()?; - - let exit_status = result.status; - let stderr = String::from_utf8(result.stderr).unwrap_or("Not displayable".into()); - let stdout = String::from_utf8(result.stdout).unwrap_or("Not displayable".into()); - - if command.print_stdout_intermediate() && exit_status.success() { - log::info!("\n{}", stdout); - } - - if print_command_success { - if exit_status.success() { - log::info!("✅ Success.") - } else { - log::error!("❌ Command failed. Run to completion for the summary."); - } - } - - Ok(RunResult { - exit_status, - stdout, - stderr, - }) -} |
