aboutsummaryrefslogtreecommitdiff
path: root/xtask/src/run
diff options
context:
space:
mode:
authordatdenkikniet <jcdra1@gmail.com>2023-04-16 13:22:10 +0200
committerdatdenkikniet <jcdra1@gmail.com>2023-04-16 13:22:10 +0200
commitbc92e43b113dae2a34db6b10812d84227ac5a6d6 (patch)
treea08dab3cb348727e69870da8a93621b3cb1c2424 /xtask/src/run
parent85e2cd6d4b1ac801dbbce2295a6617a56f9ea5a0 (diff)
Rename + better printout
Diffstat (limited to 'xtask/src/run')
-rw-r--r--xtask/src/run/mod.rs499
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,
- })
-}