diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2023-03-04 21:10:24 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-04 21:10:24 +0000 |
| commit | 7c7d6558f6d9c50fbb4d2487c98c9a5be15f2f7b (patch) | |
| tree | 80a47f0dc40059014e9448c4c2eb34c54dff45fe /xtask/src/command.rs | |
| parent | 1c5db277e4161470136dbd2a11e914ff1d383581 (diff) | |
| parent | 98c5490d94950608d31cd5ad9dd260f2f853735c (diff) | |
Merge #694
694: RTIC 2 r=AfoHT a=korken89
Co-authored-by: Emil Fresk <emil.fresk@gmail.com>
Co-authored-by: Per Lindgren <per.lindgren@ltu.se>
Diffstat (limited to 'xtask/src/command.rs')
| -rw-r--r-- | xtask/src/command.rs | 404 |
1 files changed, 353 insertions, 51 deletions
diff --git a/xtask/src/command.rs b/xtask/src/command.rs index 100888c..6e91a52 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -1,4 +1,4 @@ -use crate::{RunResult, TestRunError}; +use crate::{debug, ExtraArguments, Package, RunResult, TestRunError}; use core::fmt; use os_pipe::pipe; use std::{fs::File, io::Read, process::Command}; @@ -12,64 +12,364 @@ pub enum BuildMode { #[derive(Debug)] pub enum CargoCommand<'a> { + // For future embedded-ci + #[allow(dead_code)] Run { + cargoarg: &'a Option<&'a str>, example: &'a str, target: &'a str, - features: Option<&'a str>, + features: Option<String>, mode: BuildMode, }, - BuildAll { + Qemu { + cargoarg: &'a Option<&'a str>, + example: &'a str, + target: &'a str, + features: Option<String>, + mode: BuildMode, + }, + ExampleBuild { + cargoarg: &'a Option<&'a str>, + example: &'a str, target: &'a str, - features: Option<&'a str>, + features: Option<String>, mode: BuildMode, }, - // Size { - // example_paths: Vec<&'a Path>, - // }, - // Clean, + ExampleCheck { + cargoarg: &'a Option<&'a str>, + example: &'a str, + target: &'a str, + features: Option<String>, + mode: BuildMode, + }, + Build { + cargoarg: &'a Option<&'a str>, + package: Option<Package>, + target: &'a str, + features: Option<String>, + mode: BuildMode, + }, + Check { + cargoarg: &'a Option<&'a str>, + package: Option<Package>, + target: &'a str, + features: Option<String>, + mode: BuildMode, + }, + Clippy { + cargoarg: &'a Option<&'a str>, + package: Option<Package>, + target: &'a str, + features: Option<String>, + }, + Format { + cargoarg: &'a Option<&'a str>, + package: Option<Package>, + check_only: bool, + }, + Doc { + cargoarg: &'a Option<&'a str>, + features: Option<String>, + arguments: Option<ExtraArguments>, + }, + Test { + package: Option<Package>, + features: Option<String>, + test: Option<String>, + }, + Book { + arguments: Option<ExtraArguments>, + }, + ExampleSize { + cargoarg: &'a Option<&'a str>, + example: &'a str, + target: &'a str, + features: Option<String>, + mode: BuildMode, + arguments: Option<ExtraArguments>, + }, } impl<'a> CargoCommand<'a> { - fn name(&self) -> &str { + fn command(&self) -> &str { + match self { + CargoCommand::Run { .. } | CargoCommand::Qemu { .. } => "run", + CargoCommand::ExampleCheck { .. } | CargoCommand::Check { .. } => "check", + CargoCommand::ExampleBuild { .. } | CargoCommand::Build { .. } => "build", + CargoCommand::ExampleSize { .. } => "size", + CargoCommand::Clippy { .. } => "clippy", + CargoCommand::Format { .. } => "fmt", + CargoCommand::Doc { .. } => "doc", + CargoCommand::Book { .. } => "build", + CargoCommand::Test { .. } => "test", + } + } + pub fn executable(&self) -> &str { match self { - CargoCommand::Run { .. } => "run", - // CargoCommand::Size { example_paths: _ } => "rust-size", - CargoCommand::BuildAll { .. } => "build", + CargoCommand::Run { .. } + | CargoCommand::Qemu { .. } + | CargoCommand::ExampleCheck { .. } + | CargoCommand::Check { .. } + | CargoCommand::ExampleBuild { .. } + | CargoCommand::Build { .. } + | CargoCommand::ExampleSize { .. } + | CargoCommand::Clippy { .. } + | CargoCommand::Format { .. } + | CargoCommand::Test { .. } + | CargoCommand::Doc { .. } => "cargo", + CargoCommand::Book { .. } => "mdbook", } } pub fn args(&self) -> Vec<&str> { match self { + // For future embedded-ci, for now the same as Qemu CargoCommand::Run { + cargoarg, example, target, features, mode, } => { - let mut args = vec![ - self.name(), - "--example", - example, - "--target", - target, - "--features", - "test-critical-section", - ]; + let mut args = vec!["+nightly"]; + if let Some(cargoarg) = cargoarg { + args.extend_from_slice(&[cargoarg]); + } + args.extend_from_slice(&[self.command(), "--example", example, "--target", target]); - if let Some(feature_name) = features { - args.extend_from_slice(&["--features", feature_name]); + if let Some(feature) = features { + args.extend_from_slice(&["--features", feature]); + } + if let Some(flag) = mode.to_flag() { + args.push(flag); + } + args + } + CargoCommand::Qemu { + cargoarg, + example, + target, + features, + mode, + } => { + let mut args = vec!["+nightly"]; + if let Some(cargoarg) = cargoarg { + args.extend_from_slice(&[cargoarg]); + } + args.extend_from_slice(&[self.command(), "--example", example, "--target", target]); + + if let Some(feature) = features { + args.extend_from_slice(&["--features", feature]); } if let Some(flag) = mode.to_flag() { args.push(flag); } args } - CargoCommand::BuildAll { + CargoCommand::Build { + cargoarg, + package, target, features, mode, } => { - let mut args = vec![self.name(), "--examples", "--target", target]; + let mut args = vec!["+nightly"]; + if let Some(cargoarg) = cargoarg { + args.extend_from_slice(&[cargoarg]); + } + + args.extend_from_slice(&[self.command(), "--target", target]); + + if let Some(package) = package { + args.extend_from_slice(&["--package", package.name()]); + } + + if let Some(feature) = features { + args.extend_from_slice(&["--features", feature]); + } + if let Some(flag) = mode.to_flag() { + args.push(flag); + } + args + } + CargoCommand::Check { + cargoarg, + package, + target: _, + features, + mode, + } => { + let mut args = vec!["+nightly"]; + if let Some(cargoarg) = cargoarg { + args.extend_from_slice(&[cargoarg]); + } + args.extend_from_slice(&[self.command()]); + + if let Some(package) = package { + args.extend_from_slice(&["--package", package.name()]); + } + + if let Some(feature) = features { + args.extend_from_slice(&["--features", feature]); + } + if let Some(flag) = mode.to_flag() { + args.push(flag); + } + args + } + CargoCommand::Clippy { + cargoarg, + package, + target: _, + features, + } => { + let mut args = vec!["+nightly"]; + if let Some(cargoarg) = cargoarg { + args.extend_from_slice(&[cargoarg]); + } + + args.extend_from_slice(&[self.command()]); + + if let Some(package) = package { + args.extend_from_slice(&["--package", package.name()]); + } + + if let Some(feature) = features { + args.extend_from_slice(&["--features", feature]); + } + args + } + CargoCommand::Doc { + cargoarg, + features, + arguments, + } => { + let mut args = vec!["+nightly"]; + if let Some(cargoarg) = cargoarg { + args.extend_from_slice(&[cargoarg]); + } + + args.extend_from_slice(&[self.command()]); + + if let Some(feature) = features { + args.extend_from_slice(&["--features", feature]); + } + if let Some(ExtraArguments::Other(arguments)) = arguments { + for arg in arguments { + args.extend_from_slice(&[arg.as_str()]); + } + } + args + } + CargoCommand::Test { + package, + features, + test, + } => { + let mut args = vec!["+nightly"]; + args.extend_from_slice(&[self.command()]); + + if let Some(package) = package { + args.extend_from_slice(&["--package", package.name()]); + } + + if let Some(feature) = features { + args.extend_from_slice(&["--features", feature]); + } + if let Some(test) = test { + args.extend_from_slice(&["--test", test]); + } + args + } + CargoCommand::Book { arguments } => { + let mut args = vec![]; + + if let Some(ExtraArguments::Other(arguments)) = arguments { + for arg in arguments { + args.extend_from_slice(&[arg.as_str()]); + } + } else { + // If no argument given, run mdbook build + // with default path to book + args.extend_from_slice(&[self.command()]); + args.extend_from_slice(&["book/en"]); + } + args + } + CargoCommand::Format { + cargoarg, + package, + check_only, + } => { + let mut args = vec!["+nightly", self.command()]; + if let Some(cargoarg) = cargoarg { + args.extend_from_slice(&[cargoarg]); + } + + if let Some(package) = package { + args.extend_from_slice(&["--package", package.name()]); + } + if *check_only { + args.extend_from_slice(&["--check"]); + } + + args + } + CargoCommand::ExampleBuild { + cargoarg, + example, + target, + features, + mode, + } => { + let mut args = vec!["+nightly"]; + if let Some(cargoarg) = cargoarg { + args.extend_from_slice(&[cargoarg]); + } + args.extend_from_slice(&[self.command(), "--example", example, "--target", target]); + + if let Some(feature) = features { + args.extend_from_slice(&["--features", feature]); + } + if let Some(flag) = mode.to_flag() { + args.push(flag); + } + args + } + CargoCommand::ExampleCheck { + cargoarg, + example, + target, + features, + mode, + } => { + let mut args = vec!["+nightly"]; + if let Some(cargoarg) = cargoarg { + args.extend_from_slice(&[cargoarg]); + } + args.extend_from_slice(&[self.command(), "--example", example, "--target", target]); + + if let Some(feature) = features { + args.extend_from_slice(&["--features", feature]); + } + if let Some(flag) = mode.to_flag() { + args.push(flag); + } + args + } + CargoCommand::ExampleSize { + cargoarg, + example, + target, + features, + mode, + arguments, + } => { + let mut args = vec!["+nightly"]; + if let Some(cargoarg) = cargoarg { + args.extend_from_slice(&[cargoarg]); + } + args.extend_from_slice(&[self.command(), "--example", example, "--target", target]); if let Some(feature_name) = features { args.extend_from_slice(&["--features", feature_name]); @@ -77,25 +377,21 @@ impl<'a> CargoCommand<'a> { if let Some(flag) = mode.to_flag() { args.push(flag); } + if let Some(ExtraArguments::Other(arguments)) = arguments { + // Arguments to cargo size must be passed after "--" + args.extend_from_slice(&["--"]); + for arg in arguments { + args.extend_from_slice(&[arg.as_str()]); + } + } args - } // CargoCommand::Size { example_paths } => { - // example_paths.iter().map(|p| p.to_str().unwrap()).collect() - // } - } - } - - pub fn command(&self) -> &str { - match self { - // we need to cheat a little here: - // `cargo size` can't be ran on multiple files, so we're using `rust-size` instead – - // which isn't a command that starts wizh `cargo`. So we're sneakily swapping them out :) - // CargoCommand::Size { .. } => "rust-size", - _ => "cargo", + } } } } impl BuildMode { + #[allow(clippy::wrong_self_convention)] pub fn to_flag(&self) -> Option<&str> { match self { BuildMode::Release => Some("--release"), @@ -111,49 +407,55 @@ impl fmt::Display for BuildMode { BuildMode::Debug => "debug", }; - write!(f, "{}", cmd) + write!(f, "{cmd}") } } pub fn run_command(command: &CargoCommand) -> anyhow::Result<RunResult> { let (mut reader, writer) = pipe()?; - println!("👟 {} {}", command.command(), command.args().join(" ")); + let (mut error_reader, error_writer) = pipe()?; + debug!("👟 {} {}", command.executable(), command.args().join(" ")); - let mut handle = Command::new(command.command()) + let mut handle = Command::new(command.executable()) .args(command.args()) .stdout(writer) + .stderr(error_writer) .spawn()?; // retrieve output and clean up - let mut output = String::new(); - reader.read_to_string(&mut output)?; + let mut stdout = String::new(); + reader.read_to_string(&mut stdout)?; let exit_status = handle.wait()?; + let mut stderr = String::new(); + error_reader.read_to_string(&mut stderr)?; + Ok(RunResult { exit_status, - output, + stdout, + stderr, }) } -/// Check if `run` was sucessful. +/// 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: String) -> Result<(), TestRunError> { +pub fn run_successful(run: &RunResult, expected_output_file: &str) -> Result<(), TestRunError> { let mut file_handle = - File::open(expected_output_file.clone()).map_err(|_| TestRunError::FileError { - file: expected_output_file.clone(), + File::open(expected_output_file).map_err(|_| TestRunError::FileError { + file: expected_output_file.to_owned(), })?; let mut expected_output = String::new(); file_handle .read_to_string(&mut expected_output) .map_err(|_| TestRunError::FileError { - file: expected_output_file.clone(), + file: expected_output_file.to_owned(), })?; - if expected_output != run.output { + if expected_output != run.stdout { Err(TestRunError::FileCmpError { expected: expected_output.clone(), - got: run.output.clone(), + got: run.stdout.clone(), }) } else if !run.exit_status.success() { Err(TestRunError::CommandError(run.clone())) |
