From 582c602912592ec7ebea3096aefa02aea99c2143 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Mon, 2 Jan 2023 14:34:05 +0100 Subject: Old xtask test pass --- xtask/src/command.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'xtask/src') diff --git a/xtask/src/command.rs b/xtask/src/command.rs index 100888c..889540c 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -47,6 +47,7 @@ impl<'a> CargoCommand<'a> { mode, } => { let mut args = vec![ + "+nightly", self.name(), "--example", example, @@ -69,7 +70,7 @@ impl<'a> CargoCommand<'a> { features, mode, } => { - let mut args = vec![self.name(), "--examples", "--target", target]; + let mut args = vec!["+nightly", self.name(), "--examples", "--target", target]; if let Some(feature_name) = features { args.extend_from_slice(&["--features", feature_name]); -- cgit v1.2.3 From 9a67f00a30f14df3b9635913f728afd0b40c138d Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sun, 8 Jan 2023 19:16:36 +0100 Subject: Fix typos --- xtask/src/command.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'xtask/src') diff --git a/xtask/src/command.rs b/xtask/src/command.rs index 889540c..418f440 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -136,7 +136,7 @@ pub fn run_command(command: &CargoCommand) -> anyhow::Result { }) } -/// 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> { -- cgit v1.2.3 From 35c97b61c17a30de675eb1c7f852a100b200a0c2 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sun, 8 Jan 2023 19:56:47 +0100 Subject: All examples pass with `cargo xtask --target all` --- xtask/src/main.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 76ce04b..7eada91 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -87,12 +87,14 @@ fn main() -> anyhow::Result<()> { let targets = [ARMV7M, ARMV6M]; let examples: Vec<_> = std::fs::read_dir("./examples")? - .filter_map(|path| { - path.map(|p| p.path().file_stem().unwrap().to_str().unwrap().to_string()) - .ok() - }) + .filter_map(|p| p.ok()) + .map(|p| p.path()) + .filter(|p| p.display().to_string().ends_with(".rs")) + .map(|path| path.file_stem().unwrap().to_str().unwrap().to_string()) .collect(); + println!("examples: {examples:?}"); + let opts = Options::from_args(); let target = &opts.target; -- cgit v1.2.3 From cd790a94286cdc307d399b7f7a43e305e90de5bf Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Mon, 9 Jan 2023 21:02:53 +0100 Subject: More work on new spawn/executor --- xtask/src/command.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'xtask/src') diff --git a/xtask/src/command.rs b/xtask/src/command.rs index 418f440..4e90369 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -70,7 +70,15 @@ impl<'a> CargoCommand<'a> { features, mode, } => { - let mut args = vec!["+nightly", self.name(), "--examples", "--target", target]; + let mut args = vec![ + "+nightly", + self.name(), + "--examples", + "--target", + target, + "--features", + "test-critical-section", + ]; if let Some(feature_name) = features { args.extend_from_slice(&["--features", feature_name]); -- cgit v1.2.3 From 306aa47170fd59369b7a184924e287dc3706d64d Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Mon, 23 Jan 2023 20:05:47 +0100 Subject: Add rtic-timer (timerqueue + monotonic) and rtic-monotonics (systick-monotonic) --- xtask/src/build.rs | 13 ---- xtask/src/command.rs | 172 ------------------------------------------------- xtask/src/main.rs | 176 --------------------------------------------------- 3 files changed, 361 deletions(-) delete mode 100644 xtask/src/build.rs delete mode 100644 xtask/src/command.rs delete mode 100644 xtask/src/main.rs (limited to 'xtask/src') diff --git a/xtask/src/build.rs b/xtask/src/build.rs deleted file mode 100644 index 148a9fd..0000000 --- a/xtask/src/build.rs +++ /dev/null @@ -1,13 +0,0 @@ -use std::{fs, path::Path}; - -const HEX_BUILD_ROOT: &str = "ci/builds"; - -/// make sure we're starting with a clean,but existing slate -pub fn init_build_dir() -> anyhow::Result<()> { - if Path::new(HEX_BUILD_ROOT).exists() { - fs::remove_dir_all(HEX_BUILD_ROOT) - .map_err(|_| anyhow::anyhow!("Could not clear out directory: {}", HEX_BUILD_ROOT))?; - } - fs::create_dir_all(HEX_BUILD_ROOT) - .map_err(|_| anyhow::anyhow!("Could not create directory: {}", HEX_BUILD_ROOT)) -} diff --git a/xtask/src/command.rs b/xtask/src/command.rs deleted file mode 100644 index 4e90369..0000000 --- a/xtask/src/command.rs +++ /dev/null @@ -1,172 +0,0 @@ -use crate::{RunResult, TestRunError}; -use core::fmt; -use os_pipe::pipe; -use std::{fs::File, io::Read, process::Command}; - -#[allow(dead_code)] -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum BuildMode { - Release, - Debug, -} - -#[derive(Debug)] -pub enum CargoCommand<'a> { - Run { - example: &'a str, - target: &'a str, - features: Option<&'a str>, - mode: BuildMode, - }, - BuildAll { - target: &'a str, - features: Option<&'a str>, - mode: BuildMode, - }, - // Size { - // example_paths: Vec<&'a Path>, - // }, - // Clean, -} - -impl<'a> CargoCommand<'a> { - fn name(&self) -> &str { - match self { - CargoCommand::Run { .. } => "run", - // CargoCommand::Size { example_paths: _ } => "rust-size", - CargoCommand::BuildAll { .. } => "build", - } - } - - pub fn args(&self) -> Vec<&str> { - match self { - CargoCommand::Run { - example, - target, - features, - mode, - } => { - let mut args = vec![ - "+nightly", - self.name(), - "--example", - example, - "--target", - target, - "--features", - "test-critical-section", - ]; - - if let Some(feature_name) = features { - args.extend_from_slice(&["--features", feature_name]); - } - if let Some(flag) = mode.to_flag() { - args.push(flag); - } - args - } - CargoCommand::BuildAll { - target, - features, - mode, - } => { - let mut args = vec![ - "+nightly", - self.name(), - "--examples", - "--target", - target, - "--features", - "test-critical-section", - ]; - - if let Some(feature_name) = features { - args.extend_from_slice(&["--features", feature_name]); - } - if let Some(flag) = mode.to_flag() { - args.push(flag); - } - 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 { - pub fn to_flag(&self) -> Option<&str> { - match self { - BuildMode::Release => Some("--release"), - BuildMode::Debug => None, - } - } -} - -impl fmt::Display for BuildMode { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let cmd = match self { - BuildMode::Release => "release", - BuildMode::Debug => "debug", - }; - - write!(f, "{}", cmd) - } -} - -pub fn run_command(command: &CargoCommand) -> anyhow::Result { - let (mut reader, writer) = pipe()?; - println!("👟 {} {}", command.command(), command.args().join(" ")); - - let mut handle = Command::new(command.command()) - .args(command.args()) - .stdout(writer) - .spawn()?; - - // retrieve output and clean up - let mut output = String::new(); - reader.read_to_string(&mut output)?; - let exit_status = handle.wait()?; - - Ok(RunResult { - exit_status, - output, - }) -} - -/// 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> { - let mut file_handle = - File::open(expected_output_file.clone()).map_err(|_| TestRunError::FileError { - file: expected_output_file.clone(), - })?; - let mut expected_output = String::new(); - file_handle - .read_to_string(&mut expected_output) - .map_err(|_| TestRunError::FileError { - file: expected_output_file.clone(), - })?; - - if expected_output != run.output { - Err(TestRunError::FileCmpError { - expected: expected_output.clone(), - got: run.output.clone(), - }) - } else if !run.exit_status.success() { - Err(TestRunError::CommandError(run.clone())) - } else { - Ok(()) - } -} diff --git a/xtask/src/main.rs b/xtask/src/main.rs deleted file mode 100644 index 7eada91..0000000 --- a/xtask/src/main.rs +++ /dev/null @@ -1,176 +0,0 @@ -mod build; -mod command; - -use anyhow::bail; -use core::fmt; -use std::{ - error::Error, - ffi::OsString, - path::{Path, PathBuf}, - process, - process::ExitStatus, - str, -}; -use structopt::StructOpt; - -use crate::{ - build::init_build_dir, - command::{run_command, run_successful, BuildMode, CargoCommand}, -}; - -const ARMV6M: &str = "thumbv6m-none-eabi"; -const ARMV7M: &str = "thumbv7m-none-eabi"; - -#[derive(Debug, StructOpt)] -struct Options { - #[structopt(short, long)] - target: String, -} - -#[derive(Debug, Clone)] -pub struct RunResult { - exit_status: ExitStatus, - output: String, -} - -#[derive(Debug)] -pub enum TestRunError { - FileCmpError { expected: String, got: String }, - FileError { file: String }, - PathConversionError(OsString), - CommandError(RunResult), - IncompatibleCommand, -} - -impl fmt::Display for TestRunError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - TestRunError::FileCmpError { expected, got } => { - writeln!(f, "Differing output in files.")?; - writeln!(f, "")?; - writeln!(f, "Expected:")?; - writeln!(f, "{}", expected)?; - writeln!(f, "")?; - writeln!(f, "Got:")?; - write!(f, "{}", got) - } - TestRunError::FileError { file } => { - write!(f, "File error on: {}", file) - } - TestRunError::CommandError(e) => { - write!( - f, - "Command failed with exit status {}: {}", - e.exit_status, e.output - ) - } - TestRunError::PathConversionError(p) => { - write!(f, "Can't convert path from `OsString` to `String`: {:?}", p) - } - TestRunError::IncompatibleCommand => { - write!(f, "Can't run that command in this context") - } - } - } -} - -impl Error for TestRunError {} - -fn main() -> anyhow::Result<()> { - // if there's an `xtask` folder, we're *probably* at the root of this repo (we can't just - // check the name of `env::current_dir()` because people might clone it into a different name) - let probably_running_from_repo_root = Path::new("./xtask").exists(); - if probably_running_from_repo_root == false { - bail!("xtasks can only be executed from the root of the `cortex-m-rtic` repository"); - } - - let targets = [ARMV7M, ARMV6M]; - - let examples: Vec<_> = std::fs::read_dir("./examples")? - .filter_map(|p| p.ok()) - .map(|p| p.path()) - .filter(|p| p.display().to_string().ends_with(".rs")) - .map(|path| path.file_stem().unwrap().to_str().unwrap().to_string()) - .collect(); - - println!("examples: {examples:?}"); - - let opts = Options::from_args(); - let target = &opts.target; - - init_build_dir()?; - - if target == "all" { - for t in targets { - run_test(t, &examples)?; - } - } else if targets.contains(&target.as_str()) { - run_test(&target, &examples)?; - } else { - eprintln!( - "The target you specified is not available. Available targets are:\ - \n{:?}\n\ - as well as `all` (testing on all of the above)", - targets - ); - process::exit(1); - } - - Ok(()) -} - -fn run_test(target: &str, examples: &[String]) -> anyhow::Result<()> { - arm_example(&CargoCommand::BuildAll { - target, - features: None, - mode: BuildMode::Release, - })?; - - for example in examples { - let cmd = CargoCommand::Run { - example, - target, - features: None, - mode: BuildMode::Release, - }; - - arm_example(&cmd)?; - } - - Ok(()) -} - -// run example binary `example` -fn arm_example(command: &CargoCommand) -> anyhow::Result<()> { - match *command { - CargoCommand::Run { example, .. } => { - let run_file = format!("{}.run", example); - let expected_output_file = ["ci", "expected", &run_file] - .iter() - .collect::() - .into_os_string() - .into_string() - .map_err(|e| TestRunError::PathConversionError(e))?; - - // command is either build or run - let cargo_run_result = run_command(&command)?; - println!("{}", cargo_run_result.output); - - match &command { - CargoCommand::Run { .. } => { - run_successful(&cargo_run_result, expected_output_file)?; - } - _ => (), - } - - Ok(()) - } - CargoCommand::BuildAll { .. } => { - // command is either build or run - let cargo_run_result = run_command(&command)?; - println!("{}", cargo_run_result.output); - - Ok(()) - } // _ => Err(anyhow::Error::new(TestRunError::IncompatibleCommand)), - } -} -- cgit v1.2.3 From 9e445b3583c15c7701f3167eaa8dfe4afd541691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Sat, 4 Feb 2023 16:47:17 +0100 Subject: Move rtic macros to repo root, tune xtask --- xtask/src/build.rs | 13 +++ xtask/src/command.rs | 201 ++++++++++++++++++++++++++++++++++++++++++ xtask/src/main.rs | 240 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 454 insertions(+) create mode 100644 xtask/src/build.rs create mode 100644 xtask/src/command.rs create mode 100644 xtask/src/main.rs (limited to 'xtask/src') diff --git a/xtask/src/build.rs b/xtask/src/build.rs new file mode 100644 index 0000000..a11b4e0 --- /dev/null +++ b/xtask/src/build.rs @@ -0,0 +1,13 @@ +use std::{fs, path::Path}; + +const HEX_BUILD_ROOT: &str = "ci/builds"; + +/// Make sure we're starting with a clean, but existing slate +pub fn init_build_dir() -> anyhow::Result<()> { + if Path::new(HEX_BUILD_ROOT).exists() { + fs::remove_dir_all(HEX_BUILD_ROOT) + .map_err(|_| anyhow::anyhow!("Could not clear out directory: {}", HEX_BUILD_ROOT))?; + } + fs::create_dir_all(HEX_BUILD_ROOT) + .map_err(|_| anyhow::anyhow!("Could not create directory: {}", HEX_BUILD_ROOT)) +} diff --git a/xtask/src/command.rs b/xtask/src/command.rs new file mode 100644 index 0000000..6be1463 --- /dev/null +++ b/xtask/src/command.rs @@ -0,0 +1,201 @@ +use crate::Sizearguments; +use crate::{RunResult, TestRunError}; +use core::fmt; +use os_pipe::pipe; +use std::{fs::File, io::Read, process::Command}; + +#[allow(dead_code)] +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum BuildMode { + Release, + Debug, +} + +#[derive(Debug)] +pub enum CargoCommand<'a> { + Run { + example: &'a str, + target: &'a str, + features: Option<&'a str>, + mode: BuildMode, + }, + BuildAll { + target: &'a str, + features: Option<&'a str>, + mode: BuildMode, + }, + Size { + example: &'a str, + target: &'a str, + features: Option<&'a str>, + mode: BuildMode, + arguments: Option, + }, +} + +impl<'a> CargoCommand<'a> { + fn name(&self) -> &str { + match self { + CargoCommand::Run { .. } => "run", + CargoCommand::Size { .. } => "size", + CargoCommand::BuildAll { .. } => "build", + } + } + + pub fn args(&self) -> Vec<&str> { + match self { + CargoCommand::Run { + example, + target, + features, + mode, + } => { + let mut args = vec![ + "+nightly", + self.name(), + "--example", + example, + "--target", + target, + "--features", + "test-critical-section", + ]; + + if let Some(feature_name) = features { + args.extend_from_slice(&["--features", feature_name]); + } + if let Some(flag) = mode.to_flag() { + args.push(flag); + } + args + } + CargoCommand::BuildAll { + target, + features, + mode, + } => { + let mut args = vec![ + "+nightly", + self.name(), + "--examples", + "--target", + target, + "--features", + "test-critical-section", + ]; + + if let Some(feature_name) = features { + args.extend_from_slice(&["--features", feature_name]); + } + if let Some(flag) = mode.to_flag() { + args.push(flag); + } + args + } + CargoCommand::Size { + example, + target, + features, + mode, + arguments, + } => { + let mut args = vec![ + "+nightly", + self.name(), + "--example", + example, + "--target", + target, + "--features", + "test-critical-section", + ]; + if let Some(feature_name) = features { + args.extend_from_slice(&["--features", feature_name]); + } + if let Some(flag) = mode.to_flag() { + args.push(flag); + } + if let Some(Sizearguments::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 + } + } + } + + pub fn command(&self) -> &str { + "cargo" + } +} + +impl BuildMode { + #[allow(clippy::wrong_self_convention)] + pub fn to_flag(&self) -> Option<&str> { + match self { + BuildMode::Release => Some("--release"), + BuildMode::Debug => None, + } + } +} + +impl fmt::Display for BuildMode { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let cmd = match self { + BuildMode::Release => "release", + BuildMode::Debug => "debug", + }; + + write!(f, "{cmd}") + } +} + +pub fn run_command(command: &CargoCommand) -> anyhow::Result { + let (mut reader, writer) = pipe()?; + println!("👟 {} {}", command.command(), command.args().join(" ")); + + let mut handle = Command::new(command.command()) + .args(command.args()) + .stdout(writer) + .spawn()?; + + // retrieve output and clean up + let mut output = String::new(); + reader.read_to_string(&mut output)?; + let exit_status = handle.wait()?; + + Ok(RunResult { + exit_status, + output, + }) +} + +/// 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> { + let mut file_handle = + File::open(expected_output_file.clone()).map_err(|_| TestRunError::FileError { + file: expected_output_file.clone(), + })?; + let mut expected_output = String::new(); + file_handle + .read_to_string(&mut expected_output) + .map_err(|_| TestRunError::FileError { + file: expected_output_file.clone(), + })?; + + if expected_output != run.output { + Err(TestRunError::FileCmpError { + expected: expected_output.clone(), + got: run.output.clone(), + }) + } else if !run.exit_status.success() { + Err(TestRunError::CommandError(run.clone())) + } else { + Ok(()) + } +} diff --git a/xtask/src/main.rs b/xtask/src/main.rs new file mode 100644 index 0000000..7c0ed20 --- /dev/null +++ b/xtask/src/main.rs @@ -0,0 +1,240 @@ +mod build; +mod command; + +use anyhow::bail; +use core::fmt; +use std::{ + error::Error, + ffi::OsString, + path::{Path, PathBuf}, + process, + process::ExitStatus, + str, +}; +use structopt::StructOpt; + +use crate::{ + build::init_build_dir, + command::{run_command, run_successful, BuildMode, CargoCommand}, +}; + +const ARMV6M: &str = "thumbv6m-none-eabi"; +const ARMV7M: &str = "thumbv7m-none-eabi"; + +#[derive(Debug, StructOpt)] +struct Options { + /// For which ARM target to build: v7 or v6 + /// + /// The permissible targets are: + /// * all + /// + /// * thumbv6m-none-eabi + /// + /// * thumbv7m-none-eabi + #[structopt(short, long)] + target: String, + /// Example to run, by default all examples are run + /// + /// Example: `cargo xtask --target <..> --example complex` + #[structopt(short, long)] + example: Option, + /// Enables also running `cargo size` on the selected examples + /// + /// To pass options to `cargo size`, add `--` and then the following + /// arguments will be passed on + /// + /// Example: `cargo xtask --target <..> -s -- -A` + #[structopt(short, long)] + size: bool, + /// Options to pass to `cargo size` + #[structopt(subcommand)] + sizearguments: Option, +} + +#[derive(Clone, Debug, PartialEq, StructOpt)] +pub enum Sizearguments { + // `external_subcommand` tells structopt to put + // all the extra arguments into this Vec + #[structopt(external_subcommand)] + Other(Vec), +} + +#[derive(Debug, Clone)] +pub struct RunResult { + exit_status: ExitStatus, + output: String, +} + +#[derive(Debug)] +pub enum TestRunError { + FileCmpError { expected: String, got: String }, + FileError { file: String }, + PathConversionError(OsString), + CommandError(RunResult), + IncompatibleCommand, +} + +impl fmt::Display for TestRunError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TestRunError::FileCmpError { expected, got } => { + writeln!(f, "Differing output in files.\n")?; + writeln!(f, "Expected:")?; + writeln!(f, "{expected}\n")?; + writeln!(f, "Got:")?; + write!(f, "{got}") + } + TestRunError::FileError { file } => { + write!(f, "File error on: {file}") + } + TestRunError::CommandError(e) => { + write!( + f, + "Command failed with exit status {}: {}", + e.exit_status, e.output + ) + } + TestRunError::PathConversionError(p) => { + write!(f, "Can't convert path from `OsString` to `String`: {p:?}") + } + TestRunError::IncompatibleCommand => { + write!(f, "Can't run that command in this context") + } + } + } +} + +impl Error for TestRunError {} + +fn main() -> anyhow::Result<()> { + // if there's an `xtask` folder, we're *probably* at the root of this repo (we can't just + // check the name of `env::current_dir()` because people might clone it into a different name) + let probably_running_from_repo_root = Path::new("./xtask").exists(); + if !probably_running_from_repo_root { + bail!("xtasks can only be executed from the root of the `rtic` repository"); + } + + let targets = [ARMV7M, ARMV6M]; + + let mut examples: Vec<_> = std::fs::read_dir("./rtic/examples")? + .filter_map(|p| p.ok()) + .map(|p| p.path()) + .filter(|p| p.display().to_string().ends_with(".rs")) + .map(|path| path.file_stem().unwrap().to_str().unwrap().to_string()) + .collect(); + + println!("examples: {examples:?}"); + + let opts = Options::from_args(); + let target = &opts.target; + let check_size = opts.size; + let size_arguments = &opts.sizearguments; + let example = opts.example; + + if let Some(example) = example { + if examples.contains(&example) { + println!("\nTesting example: {example}"); + // If we managed to filter, set the examples to test to only this one + examples = vec![example] + } else { + eprintln!( + "\nThe example you specified is not available. Available examples are:\ + \n{examples:#?}\n\ + By default all examples are tested.", + ); + process::exit(1); + } + } + init_build_dir()?; + + if target == "all" { + for t in targets { + run_test(t, &examples, check_size, size_arguments)?; + } + } else if targets.contains(&target.as_str()) { + run_test(target, &examples, check_size, size_arguments)?; + } else { + eprintln!( + "The target you specified is not available. Available targets are:\ + \n{targets:?}\n\ + as well as `all` (testing on all of the above)", + ); + process::exit(1); + } + + Ok(()) +} + +fn run_test( + target: &str, + examples: &[String], + check_size: bool, + size_arguments: &Option, +) -> anyhow::Result<()> { + arm_example(&CargoCommand::BuildAll { + target, + features: None, + mode: BuildMode::Release, + })?; + + for example in examples { + let cmd = CargoCommand::Run { + example, + target, + features: None, + mode: BuildMode::Release, + }; + + arm_example(&cmd)?; + } + if check_size { + for example in examples { + arm_example(&CargoCommand::Size { + example, + target, + features: None, + mode: BuildMode::Release, + arguments: size_arguments.clone(), + })?; + } + } + + Ok(()) +} + +// run example binary `example` +fn arm_example(command: &CargoCommand) -> anyhow::Result<()> { + match *command { + CargoCommand::Run { example, .. } => { + let run_file = format!("{example}.run"); + let expected_output_file = ["rtic", "ci", "expected", &run_file] + .iter() + .collect::() + .into_os_string() + .into_string() + .map_err(TestRunError::PathConversionError)?; + + // command is either build or run + let cargo_run_result = run_command(command)?; + println!("{}", cargo_run_result.output); + + if let CargoCommand::Run { .. } = &command { + run_successful(&cargo_run_result, expected_output_file)?; + } + + Ok(()) + } + CargoCommand::BuildAll { .. } => { + // command is either build or run + let cargo_run_result = run_command(command)?; + println!("{}", cargo_run_result.output); + + Ok(()) + } + CargoCommand::Size { .. } => { + let cargo_run_result = run_command(command)?; + println!("{}", cargo_run_result.output); + Ok(()) + } + } +} -- cgit v1.2.3 From 81ba62787cd099524baa553a6bc91d287680c5e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Sat, 4 Feb 2023 16:55:29 +0100 Subject: xtask: Make target flag optional, default to all targets --- xtask/src/main.rs | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 7c0ed20..2d259dc 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -32,10 +32,10 @@ struct Options { /// /// * thumbv7m-none-eabi #[structopt(short, long)] - target: String, + target: Option, /// Example to run, by default all examples are run /// - /// Example: `cargo xtask --target <..> --example complex` + /// Example: `cargo xtask --example complex` #[structopt(short, long)] example: Option, /// Enables also running `cargo size` on the selected examples @@ -43,7 +43,7 @@ struct Options { /// To pass options to `cargo size`, add `--` and then the following /// arguments will be passed on /// - /// Example: `cargo xtask --target <..> -s -- -A` + /// Example: `cargo xtask -s -- -A` #[structopt(short, long)] size: bool, /// Options to pass to `cargo size` @@ -147,19 +147,24 @@ fn main() -> anyhow::Result<()> { } init_build_dir()?; - if target == "all" { - for t in targets { - run_test(t, &examples, check_size, size_arguments)?; + match target { + None => { + for t in targets { + println!("Testing all targets: {targets:?}"); + run_test(t, &examples, check_size, size_arguments)?; + } + } + Some(target) => { + if targets.contains(&target.as_str()) { + run_test(target, &examples, check_size, size_arguments)?; + } else { + eprintln!( + "The target you specified is not available. Available targets are:\ + \n{targets:?}\n", + ); + process::exit(1); + } } - } else if targets.contains(&target.as_str()) { - run_test(target, &examples, check_size, size_arguments)?; - } else { - eprintln!( - "The target you specified is not available. Available targets are:\ - \n{targets:?}\n\ - as well as `all` (testing on all of the above)", - ); - process::exit(1); } Ok(()) -- cgit v1.2.3 From 50e1d2d129213e286fd4321197d0c9821a034d77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Sun, 5 Feb 2023 01:50:29 +0100 Subject: Upgrade to clap v4, use log and env_logger --- xtask/src/command.rs | 131 ++++++++++++++------ xtask/src/main.rs | 342 ++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 357 insertions(+), 116 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/command.rs b/xtask/src/command.rs index 6be1463..ed73b2d 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -1,8 +1,11 @@ -use crate::Sizearguments; -use crate::{RunResult, TestRunError}; +use crate::{debug, RunResult, Sizearguments, TestRunError}; use core::fmt; use os_pipe::pipe; -use std::{fs::File, io::Read, process::Command}; +use std::{ + fs::File, + io::Read, + process::{Command, Stdio}, +}; #[allow(dead_code)] #[derive(Debug, Clone, Copy, PartialEq)] @@ -14,17 +17,32 @@ pub enum BuildMode { #[derive(Debug)] pub enum CargoCommand<'a> { Run { + cargoarg: &'a Option<&'a str>, + example: &'a str, + target: &'a str, + features: Option<&'a str>, + mode: BuildMode, + }, + Build { + cargoarg: &'a Option<&'a str>, example: &'a str, target: &'a str, features: Option<&'a str>, mode: BuildMode, }, BuildAll { + cargoarg: &'a Option<&'a str>, target: &'a str, features: Option<&'a str>, mode: BuildMode, }, + CheckAll { + cargoarg: &'a Option<&'a str>, + target: &'a str, + features: Option<&'a str>, + }, Size { + cargoarg: &'a Option<&'a str>, example: &'a str, target: &'a str, features: Option<&'a str>, @@ -37,32 +55,30 @@ impl<'a> CargoCommand<'a> { fn name(&self) -> &str { match self { CargoCommand::Run { .. } => "run", + CargoCommand::Build { .. } => "build", CargoCommand::Size { .. } => "size", CargoCommand::BuildAll { .. } => "build", + CargoCommand::CheckAll { .. } => "check", } } pub fn args(&self) -> Vec<&str> { match self { CargoCommand::Run { + cargoarg, example, target, features, mode, } => { - let mut args = vec![ - "+nightly", - 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.name(), "--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); @@ -70,22 +86,56 @@ impl<'a> CargoCommand<'a> { args } CargoCommand::BuildAll { + cargoarg, target, features, mode, } => { - let mut args = vec![ - "+nightly", - self.name(), - "--examples", - "--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.name(), "--examples", "--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::CheckAll { + cargoarg, + target, + features, + } => { + let mut args = vec!["+nightly"]; + if let Some(cargoarg) = cargoarg { + args.extend_from_slice(&[cargoarg]); + } + args.extend_from_slice(&[self.name(), "--examples", "--target", target]); + + if let Some(feature) = features { + args.extend_from_slice(&["--features", feature]); + } + args + } + CargoCommand::Build { + 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.name(), "--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); @@ -93,22 +143,19 @@ impl<'a> CargoCommand<'a> { args } CargoCommand::Size { + cargoarg, example, target, features, mode, arguments, } => { - let mut args = vec![ - "+nightly", - 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.name(), "--example", example, "--target", target]); + if let Some(feature_name) = features { args.extend_from_slice(&["--features", feature_name]); } @@ -155,11 +202,13 @@ impl fmt::Display for BuildMode { pub fn run_command(command: &CargoCommand) -> anyhow::Result { let (mut reader, writer) = pipe()?; - println!("👟 {} {}", command.command(), command.args().join(" ")); + debug!("👟 {} {}", command.command(), command.args().join(" ")); let mut handle = Command::new(command.command()) .args(command.args()) .stdout(writer) + // Throw away stderr, TODO + .stderr(Stdio::null()) .spawn()?; // retrieve output and clean up @@ -176,16 +225,16 @@ pub fn run_command(command: &CargoCommand) -> anyhow::Result { /// 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 { diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 2d259dc..47f3980 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -2,16 +2,21 @@ mod build; mod command; use anyhow::bail; +use clap::{Parser, Subcommand}; use core::fmt; use std::{ error::Error, ffi::OsString, + fs::File, + io::prelude::*, path::{Path, PathBuf}, process, process::ExitStatus, str, }; -use structopt::StructOpt; + +use env_logger::Env; +use log::{debug, error, info, log_enabled, trace, Level}; use crate::{ build::init_build_dir, @@ -21,41 +26,88 @@ use crate::{ const ARMV6M: &str = "thumbv6m-none-eabi"; const ARMV7M: &str = "thumbv7m-none-eabi"; -#[derive(Debug, StructOpt)] -struct Options { +const DEFAULT_FEATURES: Option<&str> = Some("test-critical-section"); + +#[derive(Parser)] +#[command(author, version, about, long_about = None)] +/// RTIC xtask powered testing toolbox +struct Cli { /// For which ARM target to build: v7 or v6 /// + /// Defaults to all targets if omitted. /// The permissible targets are: - /// * all - /// - /// * thumbv6m-none-eabi /// - /// * thumbv7m-none-eabi - #[structopt(short, long)] + /// thumbv6m-none-eabi + /// thumbv7m-none-eabi + #[arg(short, long)] target: Option, - /// Example to run, by default all examples are run + + /// List of comma separated examples to run, all others are excluded + /// + /// If omitted all examples are run /// - /// Example: `cargo xtask --example complex` - #[structopt(short, long)] + /// Example: `cargo xtask --example complex,spawn,init` + /// would include complex, spawn and init + #[arg(short, long, group = "example_group")] example: Option, - /// Enables also running `cargo size` on the selected examples + + /// List of comma separated examples to exclude, all others are included + /// + /// If omitted all examples are run + /// + /// Example: `cargo xtask --excludeexample complex,spawn,init` + /// would exclude complex, spawn and init + #[arg(long, group = "example_group")] + exampleexclude: Option, + + /// Enable more verbose output, repeat up to `-vvv` for even more + #[arg(short, long, action = clap::ArgAction::Count)] + verbose: u8, + + /// Subcommand picking which kind of operation + /// + /// If omitted run all tests + #[command(subcommand)] + command: Option, +} + +#[derive(Debug, Subcommand)] +enum Commands { + /// Run `cargo size` on selected or all examples /// /// To pass options to `cargo size`, add `--` and then the following /// arguments will be passed on /// - /// Example: `cargo xtask -s -- -A` - #[structopt(short, long)] - size: bool, + /// Example: `cargo xtask size -- -A` + Size(Size), + + /// Run examples in QEMU and compare against expected output + /// + /// Example runtime output is matched against `rtic/ci/expected/` + Qemu { + /// If expected output is missing or mismatching, recreate the file + /// + /// This overwrites only missing or mismatching + #[arg(long)] + overwrite_expected: bool, + }, + /// Build all examples + Build, + /// Check all examples + Check, +} + +#[derive(Debug, Parser)] +struct Size { /// Options to pass to `cargo size` - #[structopt(subcommand)] + #[command(subcommand)] sizearguments: Option, } -#[derive(Clone, Debug, PartialEq, StructOpt)] +#[derive(Clone, Debug, PartialEq, Parser)] pub enum Sizearguments { - // `external_subcommand` tells structopt to put - // all the extra arguments into this Vec - #[structopt(external_subcommand)] + /// All remaining flags and options + #[command(external_subcommand)] Other(Vec), } @@ -85,7 +137,7 @@ impl fmt::Display for TestRunError { write!(f, "{got}") } TestRunError::FileError { file } => { - write!(f, "File error on: {file}") + write!(f, "File error on: {file}\nSee flag overwrite.") } TestRunError::CommandError(e) => { write!( @@ -114,7 +166,7 @@ fn main() -> anyhow::Result<()> { bail!("xtasks can only be executed from the root of the `rtic` repository"); } - let targets = [ARMV7M, ARMV6M]; + let mut targets: Vec = [ARMV7M.to_owned(), ARMV6M.to_owned()].to_vec(); let mut examples: Vec<_> = std::fs::read_dir("./rtic/examples")? .filter_map(|p| p.ok()) @@ -123,92 +175,196 @@ fn main() -> anyhow::Result<()> { .map(|path| path.file_stem().unwrap().to_str().unwrap().to_string()) .collect(); - println!("examples: {examples:?}"); + let cli = Cli::parse(); + + let env_logger_default_level = match cli.verbose { + 0 => Env::default().default_filter_or("error"), + 1 => Env::default().default_filter_or("info"), + 2 => Env::default().default_filter_or("debug"), + _ => Env::default().default_filter_or("trace"), + }; + env_logger::Builder::from_env(env_logger_default_level) + .format_module_path(false) + .format_timestamp(None) + .init(); - let opts = Options::from_args(); - let target = &opts.target; - let check_size = opts.size; - let size_arguments = &opts.sizearguments; - let example = opts.example; + trace!("default logging level: {0}", cli.verbose); + trace!("examples: {examples:?}"); + + let target = cli.target; + let example = cli.example; if let Some(example) = example { if examples.contains(&example) { - println!("\nTesting example: {example}"); + info!("Testing example: {example}"); // If we managed to filter, set the examples to test to only this one examples = vec![example] } else { - eprintln!( + error!( "\nThe example you specified is not available. Available examples are:\ \n{examples:#?}\n\ - By default all examples are tested.", + By default if example flag is emitted, all examples are tested.", + ); + process::exit(1); + } + } + if let Some(target) = target { + if targets.contains(&target) { + debug!("\nTesting target: {target}"); + // If we managed to filter, set the targets to test to only this one + targets = vec![target] + } else { + error!( + "\nThe target you specified is not available. Available targets are:\ + \n{targets:#?}\n\ + By default all targets are tested.", ); process::exit(1); } } + init_build_dir()?; + #[allow(clippy::if_same_then_else)] + let cargoarg = if log_enabled!(Level::Trace) { + Some("-vv") + } else if log_enabled!(Level::Debug) { + Some("-v") + } else if log_enabled!(Level::Info) { + None + } else if log_enabled!(Level::Warn) || log_enabled!(Level::Error) { + Some("--quiet") + } else { + // Off case + Some("--quiet") + }; - match target { - None => { - for t in targets { - println!("Testing all targets: {targets:?}"); - run_test(t, &examples, check_size, size_arguments)?; + match cli.command { + Some(Commands::Size(arguments)) => { + debug!("Measuring on target(s): {targets:?}"); + for t in &targets { + info!("Measuring for target: {t:?}"); + build_and_check_size(&cargoarg, t, &examples, &arguments.sizearguments)?; } } - Some(target) => { - if targets.contains(&target.as_str()) { - run_test(target, &examples, check_size, size_arguments)?; - } else { - eprintln!( - "The target you specified is not available. Available targets are:\ - \n{targets:?}\n", - ); - process::exit(1); + Some(Commands::Qemu { + overwrite_expected: overwrite, + }) => { + debug!("Testing on target(s): {targets:?}"); + for t in &targets { + info!("Testing for target: {t:?}"); + run_test(&cargoarg, t, &examples, overwrite)?; + } + } + Some(Commands::Build) => { + debug!("Building for target(s): {targets:?}"); + for t in &targets { + info!("Building for target: {t:?}"); + build_all(&cargoarg, t)?; + } + } + Some(Commands::Check) => { + debug!("Checking on target(s): {targets:?}"); + for t in &targets { + info!("Checking on target: {t:?}"); + check_all(&cargoarg, t)?; } } + None => { + todo!(); + } } Ok(()) } +fn build_all(cargoarg: &Option<&str>, target: &str) -> anyhow::Result<()> { + arm_example( + &CargoCommand::BuildAll { + cargoarg, + target, + features: DEFAULT_FEATURES, + mode: BuildMode::Release, + }, + false, + )?; + Ok(()) +} + +fn check_all(cargoarg: &Option<&str>, target: &str) -> anyhow::Result<()> { + arm_example( + &CargoCommand::CheckAll { + cargoarg, + target, + features: DEFAULT_FEATURES, + }, + false, + )?; + Ok(()) +} + fn run_test( + cargoarg: &Option<&str>, target: &str, examples: &[String], - check_size: bool, - size_arguments: &Option, + overwrite: bool, ) -> anyhow::Result<()> { - arm_example(&CargoCommand::BuildAll { - target, - features: None, - mode: BuildMode::Release, - })?; - for example in examples { + let cmd = CargoCommand::Build { + cargoarg: &Some("--quiet"), + example, + target, + features: DEFAULT_FEATURES, + mode: BuildMode::Release, + }; + arm_example(&cmd, false)?; + let cmd = CargoCommand::Run { + cargoarg, example, target, - features: None, + features: DEFAULT_FEATURES, mode: BuildMode::Release, }; - arm_example(&cmd)?; + arm_example(&cmd, overwrite)?; } - if check_size { - for example in examples { - arm_example(&CargoCommand::Size { - example, - target, - features: None, - mode: BuildMode::Release, - arguments: size_arguments.clone(), - })?; - } + + Ok(()) +} + +fn build_and_check_size( + cargoarg: &Option<&str>, + target: &str, + examples: &[String], + size_arguments: &Option, +) -> anyhow::Result<()> { + for example in examples { + // Make sure the requested example(s) are built + let cmd = CargoCommand::Build { + cargoarg: &Some("--quiet"), + example, + target, + features: DEFAULT_FEATURES, + mode: BuildMode::Release, + }; + arm_example(&cmd, false)?; + + let cmd = CargoCommand::Size { + cargoarg, + example, + target, + features: DEFAULT_FEATURES, + mode: BuildMode::Release, + arguments: size_arguments.clone(), + }; + arm_example(&cmd, false)?; } Ok(()) } // run example binary `example` -fn arm_example(command: &CargoCommand) -> anyhow::Result<()> { +fn arm_example(command: &CargoCommand, overwrite: bool) -> anyhow::Result<()> { match *command { CargoCommand::Run { example, .. } => { let run_file = format!("{example}.run"); @@ -219,26 +375,62 @@ fn arm_example(command: &CargoCommand) -> anyhow::Result<()> { .into_string() .map_err(TestRunError::PathConversionError)?; - // command is either build or run + // cargo run <..> let cargo_run_result = run_command(command)?; - println!("{}", cargo_run_result.output); + info!("{}", cargo_run_result.output); - if let CargoCommand::Run { .. } = &command { - run_successful(&cargo_run_result, expected_output_file)?; + // 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!("Creating/updating file: {expected_output_file}"); + file_handle.write_all(cargo_run_result.output.as_bytes())?; + }; + } else { + run_successful(&cargo_run_result, &expected_output_file)?; + } + Ok(()) + } + CargoCommand::Build { .. } => { + // cargo run <..> + let cargo_build_result = run_command(command)?; + if !cargo_build_result.output.is_empty() { + info!("{}", cargo_build_result.output); } Ok(()) } CargoCommand::BuildAll { .. } => { - // command is either build or run - let cargo_run_result = run_command(command)?; - println!("{}", cargo_run_result.output); + // cargo build --examples + let cargo_build_result = run_command(command)?; + if !cargo_build_result.output.is_empty() { + info!("{}", cargo_build_result.output); + } + + Ok(()) + } + CargoCommand::CheckAll { .. } => { + // cargo check --examples + let cargo_check_result = run_command(command)?; + if !cargo_check_result.output.is_empty() { + info!("{}", cargo_check_result.output); + } Ok(()) } CargoCommand::Size { .. } => { - let cargo_run_result = run_command(command)?; - println!("{}", cargo_run_result.output); + // cargo size + let cargo_size_result = run_command(command)?; + if !cargo_size_result.output.is_empty() { + info!("{}", cargo_size_result.output); + } Ok(()) } } -- cgit v1.2.3 From afba4c7b14f68d589fee2de515075a339689ee95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Sun, 5 Feb 2023 02:07:20 +0100 Subject: Improve build time with Rayon --- xtask/src/main.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 47f3980..01e7934 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -4,6 +4,7 @@ mod command; use anyhow::bail; use clap::{Parser, Subcommand}; use core::fmt; +use rayon::prelude::*; use std::{ error::Error, ffi::OsString, @@ -308,7 +309,7 @@ fn run_test( examples: &[String], overwrite: bool, ) -> anyhow::Result<()> { - for example in examples { + examples.into_par_iter().for_each(|example| { let cmd = CargoCommand::Build { cargoarg: &Some("--quiet"), example, @@ -316,7 +317,7 @@ fn run_test( features: DEFAULT_FEATURES, mode: BuildMode::Release, }; - arm_example(&cmd, false)?; + arm_example(&cmd, false).unwrap(); let cmd = CargoCommand::Run { cargoarg, @@ -326,8 +327,8 @@ fn run_test( mode: BuildMode::Release, }; - arm_example(&cmd, overwrite)?; - } + arm_example(&cmd, overwrite).unwrap(); + }); Ok(()) } @@ -338,7 +339,7 @@ fn build_and_check_size( examples: &[String], size_arguments: &Option, ) -> anyhow::Result<()> { - for example in examples { + examples.into_par_iter().for_each(|example| { // Make sure the requested example(s) are built let cmd = CargoCommand::Build { cargoarg: &Some("--quiet"), @@ -347,7 +348,7 @@ fn build_and_check_size( features: DEFAULT_FEATURES, mode: BuildMode::Release, }; - arm_example(&cmd, false)?; + arm_example(&cmd, false).unwrap(); let cmd = CargoCommand::Size { cargoarg, @@ -357,8 +358,8 @@ fn build_and_check_size( mode: BuildMode::Release, arguments: size_arguments.clone(), }; - arm_example(&cmd, false)?; - } + arm_example(&cmd, false).unwrap(); + }); Ok(()) } -- cgit v1.2.3 From 6ed64610c982f4e3648b73604ac4ba190476bf3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Sun, 5 Feb 2023 19:39:29 +0100 Subject: xtask: Add thumbv8.base thumbv8.main --- xtask/src/main.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 01e7934..d05e981 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -26,6 +26,8 @@ use crate::{ const ARMV6M: &str = "thumbv6m-none-eabi"; const ARMV7M: &str = "thumbv7m-none-eabi"; +const ARMV8MBASE: &str = "thumbv8m.base-none-eabi"; +const ARMV8MMAIN: &str = "thumbv8m.main-none-eabi"; const DEFAULT_FEATURES: Option<&str> = Some("test-critical-section"); @@ -40,6 +42,8 @@ struct Cli { /// /// thumbv6m-none-eabi /// thumbv7m-none-eabi + /// thumbv8m.base-none-eabi + /// thumbv8m.main-none-eabi #[arg(short, long)] target: Option, @@ -166,10 +170,18 @@ fn main() -> anyhow::Result<()> { if !probably_running_from_repo_root { bail!("xtasks can only be executed from the root of the `rtic` repository"); } + for entry in std::fs::read_dir(".").unwrap() { - let mut targets: Vec = [ARMV7M.to_owned(), ARMV6M.to_owned()].to_vec(); - let mut examples: Vec<_> = std::fs::read_dir("./rtic/examples")? + let mut targets: Vec = [ + ARMV7M.to_owned(), + ARMV6M.to_owned(), + ARMV8MBASE.to_owned(), + ARMV8MMAIN.to_owned(), + ] + .to_vec(); + + let examples: Vec<_> = std::fs::read_dir("./rtic/examples")? .filter_map(|p| p.ok()) .map(|p| p.path()) .filter(|p| p.display().to_string().ends_with(".rs")) -- cgit v1.2.3 From d5471f2da4f9f650a42a745238fe8a5f85eed920 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Mon, 6 Feb 2023 13:03:15 +0100 Subject: xtask: Add proper diff printing in case of incorrect results --- xtask/src/main.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/main.rs b/xtask/src/main.rs index d05e981..342d654 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -130,19 +130,23 @@ pub enum TestRunError { CommandError(RunResult), IncompatibleCommand, } +use diffy::{create_patch, PatchFormatter}; impl fmt::Display for TestRunError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { TestRunError::FileCmpError { expected, got } => { + let patch = create_patch(expected, got); writeln!(f, "Differing output in files.\n")?; - writeln!(f, "Expected:")?; - writeln!(f, "{expected}\n")?; - writeln!(f, "Got:")?; - write!(f, "{got}") + let pf = PatchFormatter::new().with_color(); + writeln!(f, "{}", pf.fmt_patch(&patch))?; + write!( + f, + "See flag --overwrite-expected to create/update expected output." + ) } TestRunError::FileError { file } => { - write!(f, "File error on: {file}\nSee flag overwrite.") + write!(f, "File error on: {file}\nSee flag --overwrite-expected to create/update expected output.") } TestRunError::CommandError(e) => { write!( @@ -403,6 +407,7 @@ fn arm_example(command: &CargoCommand, overwrite: bool) -> anyhow::Result<()> { file: expected_output_file.clone(), } })?; + info!("Flag --overwrite-expected enabled"); info!("Creating/updating file: {expected_output_file}"); file_handle.write_all(cargo_run_result.output.as_bytes())?; }; -- cgit v1.2.3 From 806b3668e8c54b894d3d096f3d28474c32a60505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Mon, 6 Feb 2023 13:21:04 +0100 Subject: xtask: Major overhaul Fix error printouts for examples, Rename BuildAll -> Build Rename Build -> ExampleBuild Command interface changed, targets by defalt only v6 and v7 --- xtask/src/command.rs | 155 +++++++++++++++++---- xtask/src/main.rs | 376 +++++++++++++++++++++++++++++++++++---------------- 2 files changed, 395 insertions(+), 136 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/command.rs b/xtask/src/command.rs index ed73b2d..07ecc84 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -1,11 +1,7 @@ -use crate::{debug, RunResult, Sizearguments, TestRunError}; +use crate::{debug, info, RunResult, Sizearguments, TestRunError}; use core::fmt; use os_pipe::pipe; -use std::{ - fs::File, - io::Read, - process::{Command, Stdio}, -}; +use std::{fs::File, io::Read, process::Command}; #[allow(dead_code)] #[derive(Debug, Clone, Copy, PartialEq)] @@ -16,6 +12,8 @@ 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, @@ -23,25 +21,47 @@ pub enum CargoCommand<'a> { features: Option<&'a str>, mode: BuildMode, }, - Build { + Qemu { cargoarg: &'a Option<&'a str>, example: &'a str, target: &'a str, features: Option<&'a str>, mode: BuildMode, }, - BuildAll { + ExampleBuild { cargoarg: &'a Option<&'a str>, + example: &'a str, target: &'a str, features: Option<&'a str>, mode: BuildMode, }, - CheckAll { + ExampleCheck { cargoarg: &'a Option<&'a str>, + example: &'a str, target: &'a str, features: Option<&'a str>, + mode: BuildMode, }, - Size { + Build { + cargoarg: &'a Option<&'a str>, + package: Vec, + target: &'a str, + features: Option<&'a str>, + mode: BuildMode, + }, + Check { + cargoarg: &'a Option<&'a str>, + package: Vec, + target: &'a str, + features: Option<&'a str>, + }, + Clippy { + cargoarg: &'a Option<&'a str>, + package: Vec, + target: &'a str, + features: Option<&'a str>, + }, + ExampleSize { cargoarg: &'a Option<&'a str>, example: &'a str, target: &'a str, @@ -54,16 +74,21 @@ pub enum CargoCommand<'a> { impl<'a> CargoCommand<'a> { fn name(&self) -> &str { match self { - CargoCommand::Run { .. } => "run", - CargoCommand::Build { .. } => "build", - CargoCommand::Size { .. } => "size", - CargoCommand::BuildAll { .. } => "build", - CargoCommand::CheckAll { .. } => "check", + CargoCommand::Run { .. } | CargoCommand::Qemu { .. } => "run", + CargoCommand::ExampleCheck { .. } | CargoCommand::Check { .. } => "check", + CargoCommand::ExampleBuild { .. } | CargoCommand::Build { .. } => "build", + CargoCommand::ExampleSize { .. } => "size", + CargoCommand::Clippy { .. } => "clippy", + // TODO + // CargoCommand::Fmt { .. } => "fmt", + // CargoCommand::Test { .. } => "test", + // CargoCommand::Doc { .. } => "doc", } } pub fn args(&self) -> Vec<&str> { match self { + // For future embedded-ci, for now the same as Qemu CargoCommand::Run { cargoarg, example, @@ -85,8 +110,9 @@ impl<'a> CargoCommand<'a> { } args } - CargoCommand::BuildAll { + CargoCommand::Qemu { cargoarg, + example, target, features, mode, @@ -95,7 +121,7 @@ impl<'a> CargoCommand<'a> { if let Some(cargoarg) = cargoarg { args.extend_from_slice(&[cargoarg]); } - args.extend_from_slice(&[self.name(), "--examples", "--target", target]); + args.extend_from_slice(&[self.name(), "--example", example, "--target", target]); if let Some(feature) = features { args.extend_from_slice(&["--features", feature]); @@ -105,23 +131,100 @@ impl<'a> CargoCommand<'a> { } args } - CargoCommand::CheckAll { + CargoCommand::Build { 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.name(), "--examples", "--target", target]); + + args.extend_from_slice(&[self.name(), "--target", target]); + if !package.is_empty() { + for package in package { + args.extend_from_slice(&["--package", package]); + } + } if let Some(feature) = features { args.extend_from_slice(&["--features", feature]); } + if let Some(flag) = mode.to_flag() { + args.push(flag); + } args } - CargoCommand::Build { + CargoCommand::Check { + cargoarg, + package, + target, + features, + } => { + let mut args = vec!["+nightly"]; + if let Some(cargoarg) = cargoarg { + args.extend_from_slice(&[cargoarg]); + } + args.extend_from_slice(&[self.name(), "--target", target]); + if !package.is_empty() { + for package in package { + args.extend_from_slice(&["--package", package]); + } + } + + if let Some(feature) = features { + args.extend_from_slice(&["--features", feature]); + } + 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.name(), "--target", target]); + if !package.is_empty() { + for package in package { + args.extend_from_slice(&["--package", package]); + } + } + + if let Some(feature) = features { + args.extend_from_slice(&["--features", feature]); + } + 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.name(), "--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, @@ -142,7 +245,7 @@ impl<'a> CargoCommand<'a> { } args } - CargoCommand::Size { + CargoCommand::ExampleSize { cargoarg, example, target, @@ -202,13 +305,13 @@ impl fmt::Display for BuildMode { pub fn run_command(command: &CargoCommand) -> anyhow::Result { let (mut reader, writer) = pipe()?; + let (mut error_reader, error_writer) = pipe()?; debug!("👟 {} {}", command.command(), command.args().join(" ")); let mut handle = Command::new(command.command()) .args(command.args()) .stdout(writer) - // Throw away stderr, TODO - .stderr(Stdio::null()) + .stderr(error_writer) .spawn()?; // retrieve output and clean up @@ -216,6 +319,12 @@ pub fn run_command(command: &CargoCommand) -> anyhow::Result { reader.read_to_string(&mut output)?; let exit_status = handle.wait()?; + let mut error_output = String::new(); + error_reader.read_to_string(&mut error_output)?; + if !error_output.is_empty() { + info!("{error_output}"); + } + Ok(RunResult { exit_status, output, diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 342d654..182ba2b 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -2,7 +2,7 @@ mod build; mod command; use anyhow::bail; -use clap::{Parser, Subcommand}; +use clap::{Args, Parser, Subcommand}; use core::fmt; use rayon::prelude::*; use std::{ @@ -24,6 +24,8 @@ use crate::{ command::{run_command, run_successful, BuildMode, CargoCommand}, }; +// x86_64-unknown-linux-gnu +const _X86_64: &str = "x86_64-unknown-linux-gnu"; const ARMV6M: &str = "thumbv6m-none-eabi"; const ARMV7M: &str = "thumbv7m-none-eabi"; const ARMV8MBASE: &str = "thumbv8m.base-none-eabi"; @@ -35,10 +37,14 @@ const DEFAULT_FEATURES: Option<&str> = Some("test-critical-section"); #[command(author, version, about, long_about = None)] /// RTIC xtask powered testing toolbox struct Cli { - /// For which ARM target to build: v7 or v6 + /// For which target to build /// - /// Defaults to all targets if omitted. - /// The permissible targets are: + /// Defaults to these targets if omitted: + /// + /// thumbv6m-none-eabi + /// thumbv7m-none-eabi + /// + /// The valid targets are: /// /// thumbv6m-none-eabi /// thumbv7m-none-eabi @@ -47,9 +53,9 @@ struct Cli { #[arg(short, long)] target: Option, - /// List of comma separated examples to run, all others are excluded + /// List of comma separated examples to include, all others are excluded /// - /// If omitted all examples are run + /// If omitted all examples are included /// /// Example: `cargo xtask --example complex,spawn,init` /// would include complex, spawn and init @@ -58,7 +64,7 @@ struct Cli { /// List of comma separated examples to exclude, all others are included /// - /// If omitted all examples are run + /// If omitted all examples are included /// /// Example: `cargo xtask --excludeexample complex,spawn,init` /// would exclude complex, spawn and init @@ -69,11 +75,9 @@ struct Cli { #[arg(short, long, action = clap::ArgAction::Count)] verbose: u8, - /// Subcommand picking which kind of operation - /// - /// If omitted run all tests + /// Subcommand selecting operation #[command(subcommand)] - command: Option, + command: Commands, } #[derive(Debug, Subcommand)] @@ -89,17 +93,51 @@ enum Commands { /// Run examples in QEMU and compare against expected output /// /// Example runtime output is matched against `rtic/ci/expected/` - Qemu { - /// If expected output is missing or mismatching, recreate the file - /// - /// This overwrites only missing or mismatching - #[arg(long)] - overwrite_expected: bool, - }, + /// + /// Requires that an ARM target is selected + Qemu(QemuAndRun), + + /// Run examples through embedded-ci and compare against expected output + /// + /// unimplemented!() For now TODO, equal to Qemu + /// + /// Example runtime output is matched against `rtic/ci/expected/` + /// + /// Requires that an ARM target is selected + Run(QemuAndRun), + /// Build all examples - Build, - /// Check all examples - Check, + ExampleBuild, + + /// Check all packages + ExampleCheck, + + /// Build all examples + Build(Package), + + /// Check all packages + Check(Package), + + /// Run clippy + Clippy(Package), +} + +#[derive(Args, Debug)] +/// Restrict to package, or run on whole workspace +struct Package { + /// For which package/workspace member to operate + /// + /// If omitted, work on all + package: Option, +} + +#[derive(Args, Debug)] +struct QemuAndRun { + /// If expected output is missing or mismatching, recreate the file + /// + /// This overwrites only missing or mismatching + #[arg(long)] + overwrite_expected: bool, } #[derive(Debug, Parser)] @@ -174,16 +212,8 @@ fn main() -> anyhow::Result<()> { if !probably_running_from_repo_root { bail!("xtasks can only be executed from the root of the `rtic` repository"); } - for entry in std::fs::read_dir(".").unwrap() { - - let mut targets: Vec = [ - ARMV7M.to_owned(), - ARMV6M.to_owned(), - ARMV8MBASE.to_owned(), - ARMV8MMAIN.to_owned(), - ] - .to_vec(); + let mut targets: Vec = [ARMV7M.to_owned(), ARMV6M.to_owned()].to_vec(); let examples: Vec<_> = std::fs::read_dir("./rtic/examples")? .filter_map(|p| p.ok()) @@ -206,27 +236,14 @@ fn main() -> anyhow::Result<()> { .init(); trace!("default logging level: {0}", cli.verbose); - trace!("examples: {examples:?}"); let target = cli.target; - let example = cli.example; - - if let Some(example) = example { - if examples.contains(&example) { - info!("Testing example: {example}"); - // If we managed to filter, set the examples to test to only this one - examples = vec![example] - } else { - error!( - "\nThe example you specified is not available. Available examples are:\ - \n{examples:#?}\n\ - By default if example flag is emitted, all examples are tested.", - ); - process::exit(1); - } - } if let Some(target) = target { - if targets.contains(&target) { + let mut targets_extended = targets.clone(); + targets_extended.push(ARMV8MBASE.to_owned()); + targets_extended.push(ARMV8MMAIN.to_owned()); + + if targets_extended.contains(&target) { debug!("\nTesting target: {target}"); // If we managed to filter, set the targets to test to only this one targets = vec![target] @@ -240,66 +257,129 @@ fn main() -> anyhow::Result<()> { } } + let example = cli.example; + let exampleexclude = cli.exampleexclude; + + let examples_to_run = { + let mut examples_to_run = examples.clone(); + + if let Some(example) = example { + examples_to_run = examples.clone(); + let examples_to_exclude = example.split(',').collect::>(); + // From the list of all examples, remove all not listed as included + for ex in examples_to_exclude { + examples_to_run.retain(|x| *x.as_str() == *ex); + } + }; + + if let Some(example) = exampleexclude { + examples_to_run = examples.clone(); + let examples_to_exclude = example.split(',').collect::>(); + // From the list of all examples, remove all those listed as excluded + for ex in examples_to_exclude { + examples_to_run.retain(|x| *x.as_str() != *ex); + } + }; + + if log_enabled!(Level::Trace) { + trace!("All examples:\n{examples:?} number: {}", examples.len()); + trace!( + "examples_to_run:\n{examples_to_run:?} number: {}", + examples_to_run.len() + ); + } + + if examples_to_run.is_empty() { + error!( + "\nThe example(s) you specified is not available. Available examples are:\ + \n{examples:#?}\n\ + By default if example flag is emitted, all examples are tested.", + ); + process::exit(1); + } else { + } + examples_to_run + }; + init_build_dir()?; #[allow(clippy::if_same_then_else)] let cargoarg = if log_enabled!(Level::Trace) { - Some("-vv") - } else if log_enabled!(Level::Debug) { Some("-v") + } else if log_enabled!(Level::Debug) { + None } else if log_enabled!(Level::Info) { None } else if log_enabled!(Level::Warn) || log_enabled!(Level::Error) { - Some("--quiet") + None } else { // Off case Some("--quiet") }; match cli.command { - Some(Commands::Size(arguments)) => { + Commands::Size(arguments) => { debug!("Measuring on target(s): {targets:?}"); + // x86_64 target not valid for t in &targets { info!("Measuring for target: {t:?}"); - build_and_check_size(&cargoarg, t, &examples, &arguments.sizearguments)?; + build_and_check_size(&cargoarg, t, &examples_to_run, &arguments.sizearguments)?; } } - Some(Commands::Qemu { - overwrite_expected: overwrite, - }) => { - debug!("Testing on target(s): {targets:?}"); + Commands::Qemu(args) | Commands::Run(args) => { + debug!("Running on target(s): {targets:?}"); + // x86_64 target not valid for t in &targets { info!("Testing for target: {t:?}"); - run_test(&cargoarg, t, &examples, overwrite)?; + run_test(&cargoarg, t, &examples_to_run, args.overwrite_expected)?; } } - Some(Commands::Build) => { + Commands::ExampleBuild => { debug!("Building for target(s): {targets:?}"); for t in &targets { info!("Building for target: {t:?}"); - build_all(&cargoarg, t)?; + example_build(&cargoarg, t, &examples_to_run)?; } } - Some(Commands::Check) => { + Commands::ExampleCheck => { debug!("Checking on target(s): {targets:?}"); for t in &targets { info!("Checking on target: {t:?}"); - check_all(&cargoarg, t)?; + example_check(&cargoarg, t, &examples_to_run)?; } } - None => { - todo!(); + Commands::Build(args) => { + debug!("Building for target(s): {targets:?}"); + for t in &targets { + info!("Building for target: {t:?}"); + cargo_build(&cargoarg, &args, t)?; + } + } + Commands::Check(args) => { + debug!("Checking on target(s): {targets:?}"); + for t in &targets { + info!("Checking on target: {t:?}"); + cargo_check(&cargoarg, &args, t)?; + } + } + Commands::Clippy(args) => { + debug!("Clippy on target(s): {targets:?}"); + for t in &targets { + info!("Running clippy on target: {t:?}"); + cargo_clippy(&cargoarg, &args, t)?; + } } } Ok(()) } -fn build_all(cargoarg: &Option<&str>, target: &str) -> anyhow::Result<()> { - arm_example( - &CargoCommand::BuildAll { +fn cargo_build(cargoarg: &Option<&str>, package: &Package, target: &str) -> anyhow::Result<()> { + command_parser( + &CargoCommand::Build { cargoarg, + package: package_filter(package), target, - features: DEFAULT_FEATURES, + features: None, mode: BuildMode::Release, }, false, @@ -307,12 +387,26 @@ fn build_all(cargoarg: &Option<&str>, target: &str) -> anyhow::Result<()> { Ok(()) } -fn check_all(cargoarg: &Option<&str>, target: &str) -> anyhow::Result<()> { - arm_example( - &CargoCommand::CheckAll { +fn cargo_check(cargoarg: &Option<&str>, package: &Package, target: &str) -> anyhow::Result<()> { + command_parser( + &CargoCommand::Check { cargoarg, + package: package_filter(package), target, - features: DEFAULT_FEATURES, + features: None, + }, + false, + )?; + Ok(()) +} + +fn cargo_clippy(cargoarg: &Option<&str>, package: &Package, target: &str) -> anyhow::Result<()> { + command_parser( + &CargoCommand::Clippy { + cargoarg, + package: package_filter(package), + target, + features: None, }, false, )?; @@ -326,16 +420,53 @@ fn run_test( overwrite: bool, ) -> anyhow::Result<()> { examples.into_par_iter().for_each(|example| { - let cmd = CargoCommand::Build { + let cmd = CargoCommand::ExampleBuild { cargoarg: &Some("--quiet"), example, target, features: DEFAULT_FEATURES, mode: BuildMode::Release, }; - arm_example(&cmd, false).unwrap(); + if let Err(err) = command_parser(&cmd, false) { + error!("{err}"); + } + + let cmd = CargoCommand::Qemu { + cargoarg, + example, + target, + features: DEFAULT_FEATURES, + mode: BuildMode::Release, + }; + + if let Err(err) = command_parser(&cmd, overwrite) { + error!("{err}"); + } + }); + + Ok(()) +} +fn example_check(cargoarg: &Option<&str>, target: &str, examples: &[String]) -> anyhow::Result<()> { + examples.into_par_iter().for_each(|example| { + let cmd = CargoCommand::ExampleCheck { + cargoarg, + example, + target, + features: DEFAULT_FEATURES, + mode: BuildMode::Release, + }; - let cmd = CargoCommand::Run { + if let Err(err) = command_parser(&cmd, overwrite) { + error!("{err}"); + } + }); + + Ok(()) +} + +fn example_build(cargoarg: &Option<&str>, target: &str, examples: &[String]) -> anyhow::Result<()> { + examples.into_par_iter().for_each(|example| { + let cmd = CargoCommand::ExampleBuild { cargoarg, example, target, @@ -343,7 +474,9 @@ fn run_test( mode: BuildMode::Release, }; - arm_example(&cmd, overwrite).unwrap(); + if let Err(err) = command_parser(&cmd, overwrite) { + error!("{err}"); + } }); Ok(()) @@ -357,16 +490,18 @@ fn build_and_check_size( ) -> anyhow::Result<()> { examples.into_par_iter().for_each(|example| { // Make sure the requested example(s) are built - let cmd = CargoCommand::Build { + let cmd = CargoCommand::ExampleBuild { cargoarg: &Some("--quiet"), example, target, features: DEFAULT_FEATURES, mode: BuildMode::Release, }; - arm_example(&cmd, false).unwrap(); + if let Err(err) = command_parser(&cmd, false) { + error!("{err}"); + } - let cmd = CargoCommand::Size { + let cmd = CargoCommand::ExampleSize { cargoarg, example, target, @@ -374,16 +509,52 @@ fn build_and_check_size( mode: BuildMode::Release, arguments: size_arguments.clone(), }; - arm_example(&cmd, false).unwrap(); + if let Err(err) = command_parser(&cmd, false) { + error!("{err}"); + } }); Ok(()) } +fn package_filter(package: &Package) -> Vec { + // TODO Parse Cargo.toml workspace definition instead? + let packages: Vec = [ + "rtic".to_owned(), + "rtic-macros".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(1); + } + } else { + package_selected = packages; + } + package_selected +} + // run example binary `example` -fn arm_example(command: &CargoCommand, overwrite: bool) -> anyhow::Result<()> { +fn command_parser(command: &CargoCommand, overwrite: bool) -> anyhow::Result<()> { match *command { - CargoCommand::Run { example, .. } => { + CargoCommand::Qemu { example, .. } | CargoCommand::Run { example, .. } => { let run_file = format!("{example}.run"); let expected_output_file = ["rtic", "ci", "expected", &run_file] .iter() @@ -393,6 +564,7 @@ fn arm_example(command: &CargoCommand, overwrite: bool) -> anyhow::Result<()> { .map_err(TestRunError::PathConversionError)?; // cargo run <..> + info!("Running example: {example}"); let cargo_run_result = run_command(command)?; info!("{}", cargo_run_result.output); @@ -416,40 +588,18 @@ fn arm_example(command: &CargoCommand, overwrite: bool) -> anyhow::Result<()> { } Ok(()) } - CargoCommand::Build { .. } => { - // cargo run <..> - let cargo_build_result = run_command(command)?; - if !cargo_build_result.output.is_empty() { - info!("{}", cargo_build_result.output); + CargoCommand::ExampleBuild { .. } + | CargoCommand::ExampleCheck { .. } + | CargoCommand::Build { .. } + | CargoCommand::Check { .. } + | CargoCommand::Clippy { .. } + | CargoCommand::ExampleSize { .. } => { + let cargo_result = run_command(command)?; + if !cargo_result.output.is_empty() { + info!("{}", cargo_result.output); } Ok(()) } - CargoCommand::BuildAll { .. } => { - // cargo build --examples - let cargo_build_result = run_command(command)?; - if !cargo_build_result.output.is_empty() { - info!("{}", cargo_build_result.output); - } - - Ok(()) - } - CargoCommand::CheckAll { .. } => { - // cargo check --examples - let cargo_check_result = run_command(command)?; - if !cargo_check_result.output.is_empty() { - info!("{}", cargo_check_result.output); - } - - Ok(()) - } - CargoCommand::Size { .. } => { - // cargo size - let cargo_size_result = run_command(command)?; - if !cargo_size_result.output.is_empty() { - info!("{}", cargo_size_result.output); - } - Ok(()) - } } } -- cgit v1.2.3 From 7bcbdf73062ba78c957513c7e38065410dfb67ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Mon, 6 Feb 2023 13:41:01 +0100 Subject: xtask: Fixup, copy paste fail --- xtask/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 182ba2b..1a3d52f 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -456,7 +456,7 @@ fn example_check(cargoarg: &Option<&str>, target: &str, examples: &[String]) -> mode: BuildMode::Release, }; - if let Err(err) = command_parser(&cmd, overwrite) { + if let Err(err) = command_parser(&cmd, false) { error!("{err}"); } }); @@ -474,7 +474,7 @@ fn example_build(cargoarg: &Option<&str>, target: &str, examples: &[String]) -> mode: BuildMode::Release, }; - if let Err(err) = command_parser(&cmd, overwrite) { + if let Err(err) = command_parser(&cmd, false) { error!("{err}"); } }); -- cgit v1.2.3 From 865382325813653c59384066e3e460e857d478f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Mon, 6 Feb 2023 13:48:52 +0100 Subject: xtask: For now test on ARM --- xtask/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'xtask/src') diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 1a3d52f..590f093 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -521,7 +521,7 @@ fn package_filter(package: &Package) -> Vec { // TODO Parse Cargo.toml workspace definition instead? let packages: Vec = [ "rtic".to_owned(), - "rtic-macros".to_owned(), + "rtic-arbiter".to_owned(), "rtic-channel".to_owned(), "rtic-common".to_owned(), "rtic-macros".to_owned(), -- cgit v1.2.3 From 10a896ab9b0089a5ff9af4870488a6c604887cc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Wed, 8 Feb 2023 22:09:32 +0100 Subject: xtask: Propagate stdio/stderr, exitcodes --- xtask/src/command.rs | 20 +++++++++----------- xtask/src/main.rs | 36 +++++++++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 20 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/command.rs b/xtask/src/command.rs index 07ecc84..d894fae 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -1,4 +1,4 @@ -use crate::{debug, info, RunResult, Sizearguments, TestRunError}; +use crate::{debug, RunResult, Sizearguments, TestRunError}; use core::fmt; use os_pipe::pipe; use std::{fs::File, io::Read, process::Command}; @@ -315,19 +315,17 @@ pub fn run_command(command: &CargoCommand) -> anyhow::Result { .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 error_output = String::new(); - error_reader.read_to_string(&mut error_output)?; - if !error_output.is_empty() { - info!("{error_output}"); - } + let mut stderr = String::new(); + error_reader.read_to_string(&mut stderr)?; Ok(RunResult { exit_status, - output, + stdout, + stderr, }) } @@ -346,10 +344,10 @@ pub fn run_successful(run: &RunResult, expected_output_file: &str) -> Result<(), 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())) diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 590f093..e0bb872 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -17,6 +17,7 @@ use std::{ }; use env_logger::Env; +use exitcode; use log::{debug, error, info, log_enabled, trace, Level}; use crate::{ @@ -157,7 +158,8 @@ pub enum Sizearguments { #[derive(Debug, Clone)] pub struct RunResult { exit_status: ExitStatus, - output: String, + stdout: String, + stderr: String, } #[derive(Debug)] @@ -190,7 +192,7 @@ impl fmt::Display for TestRunError { write!( f, "Command failed with exit status {}: {}", - e.exit_status, e.output + e.exit_status, e.stdout ) } TestRunError::PathConversionError(p) => { @@ -253,7 +255,7 @@ fn main() -> anyhow::Result<()> { \n{targets:#?}\n\ By default all targets are tested.", ); - process::exit(1); + process::exit(exitcode::USAGE); } } @@ -295,7 +297,7 @@ fn main() -> anyhow::Result<()> { \n{examples:#?}\n\ By default if example flag is emitted, all examples are tested.", ); - process::exit(1); + process::exit(exitcode::USAGE); } else { } examples_to_run @@ -543,7 +545,7 @@ fn package_filter(package: &Package) -> Vec { \n{packages:#?}\n\ By default all packages are tested.", ); - process::exit(1); + process::exit(exitcode::USAGE); } } else { package_selected = packages; @@ -566,7 +568,7 @@ fn command_parser(command: &CargoCommand, overwrite: bool) -> anyhow::Result<()> // cargo run <..> info!("Running example: {example}"); let cargo_run_result = run_command(command)?; - info!("{}", cargo_run_result.output); + info!("{}", cargo_run_result.stdout); // Create a file for the expected output if it does not exist or mismatches if overwrite { @@ -581,7 +583,7 @@ fn command_parser(command: &CargoCommand, overwrite: bool) -> anyhow::Result<()> })?; info!("Flag --overwrite-expected enabled"); info!("Creating/updating file: {expected_output_file}"); - file_handle.write_all(cargo_run_result.output.as_bytes())?; + file_handle.write_all(cargo_run_result.stdout.as_bytes())?; }; } else { run_successful(&cargo_run_result, &expected_output_file)?; @@ -595,8 +597,24 @@ fn command_parser(command: &CargoCommand, overwrite: bool) -> anyhow::Result<()> | CargoCommand::Clippy { .. } | CargoCommand::ExampleSize { .. } => { let cargo_result = run_command(command)?; - if !cargo_result.output.is_empty() { - info!("{}", cargo_result.output); + if let Some(exit_code) = cargo_result.exit_status.code() { + if exit_code != exitcode::OK { + error!("Exit code from command: {exit_code}"); + if !cargo_result.stdout.is_empty() { + info!("{}", cargo_result.stdout); + } + if !cargo_result.stderr.is_empty() { + error!("{}", cargo_result.stderr); + } + process::exit(exit_code); + } else { + if !cargo_result.stdout.is_empty() { + info!("{}", cargo_result.stdout); + } + if !cargo_result.stderr.is_empty() { + info!("{}", cargo_result.stderr); + } + } } Ok(()) -- cgit v1.2.3 From 9552790dcc5c8469c6c297b0277a83d2c145b56b Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Mon, 20 Feb 2023 20:09:51 +0100 Subject: Fix xtask to work with backends --- xtask/src/main.rs | 206 +++++++++++++++++++++++++++++------------------------- 1 file changed, 112 insertions(+), 94 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/main.rs b/xtask/src/main.rs index e0bb872..b270a44 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -32,27 +32,44 @@ const ARMV7M: &str = "thumbv7m-none-eabi"; const ARMV8MBASE: &str = "thumbv8m.base-none-eabi"; const ARMV8MMAIN: &str = "thumbv8m.main-none-eabi"; -const DEFAULT_FEATURES: Option<&str> = Some("test-critical-section"); +const DEFAULT_FEATURES: &str = "test-critical-section"; + +#[derive(clap::ValueEnum, Copy, Clone, Default, Debug)] +enum Backends { + Thumbv6, + #[default] + Thumbv7, + Thumbv8Base, + Thumbv8Main, +} + +impl Backends { + fn to_target(&self) -> &str { + match self { + Backends::Thumbv6 => ARMV6M, + Backends::Thumbv7 => ARMV7M, + Backends::Thumbv8Base => ARMV8MBASE, + Backends::Thumbv8Main => ARMV8MMAIN, + } + } + + fn to_rtic_feature(&self) -> &str { + match self { + Backends::Thumbv6 => "thumbv6", + Backends::Thumbv7 => "thumbv7", + Backends::Thumbv8Base => "thumbv8_base", + Backends::Thumbv8Main => "thumbv8_main", + } + } +} #[derive(Parser)] #[command(author, version, about, long_about = None)] /// RTIC xtask powered testing toolbox struct Cli { - /// For which target to build - /// - /// Defaults to these targets if omitted: - /// - /// thumbv6m-none-eabi - /// thumbv7m-none-eabi - /// - /// The valid targets are: - /// - /// thumbv6m-none-eabi - /// thumbv7m-none-eabi - /// thumbv8m.base-none-eabi - /// thumbv8m.main-none-eabi - #[arg(short, long)] - target: Option, + /// For which backend to build + #[arg(value_enum, short, long)] + backend: Backends, /// List of comma separated examples to include, all others are excluded /// @@ -215,8 +232,6 @@ fn main() -> anyhow::Result<()> { bail!("xtasks can only be executed from the root of the `rtic` repository"); } - let mut targets: Vec = [ARMV7M.to_owned(), ARMV6M.to_owned()].to_vec(); - let examples: Vec<_> = std::fs::read_dir("./rtic/examples")? .filter_map(|p| p.ok()) .map(|p| p.path()) @@ -239,25 +254,7 @@ fn main() -> anyhow::Result<()> { trace!("default logging level: {0}", cli.verbose); - let target = cli.target; - if let Some(target) = target { - let mut targets_extended = targets.clone(); - targets_extended.push(ARMV8MBASE.to_owned()); - targets_extended.push(ARMV8MMAIN.to_owned()); - - if targets_extended.contains(&target) { - debug!("\nTesting target: {target}"); - // If we managed to filter, set the targets to test to only this one - targets = vec![target] - } else { - error!( - "\nThe target you specified is not available. Available targets are:\ - \n{targets:#?}\n\ - By default all targets are tested.", - ); - process::exit(exitcode::USAGE); - } - } + let backend = cli.backend; let example = cli.example; let exampleexclude = cli.exampleexclude; @@ -320,67 +317,60 @@ fn main() -> anyhow::Result<()> { match cli.command { Commands::Size(arguments) => { - debug!("Measuring on target(s): {targets:?}"); // x86_64 target not valid - for t in &targets { - info!("Measuring for target: {t:?}"); - build_and_check_size(&cargoarg, t, &examples_to_run, &arguments.sizearguments)?; - } + info!("Measuring for backend: {backend:?}"); + build_and_check_size( + &cargoarg, + backend, + &examples_to_run, + &arguments.sizearguments, + )?; } Commands::Qemu(args) | Commands::Run(args) => { - debug!("Running on target(s): {targets:?}"); // x86_64 target not valid - for t in &targets { - info!("Testing for target: {t:?}"); - run_test(&cargoarg, t, &examples_to_run, args.overwrite_expected)?; - } + info!("Testing for backend: {backend:?}"); + run_test( + &cargoarg, + backend, + &examples_to_run, + args.overwrite_expected, + )?; } Commands::ExampleBuild => { - debug!("Building for target(s): {targets:?}"); - for t in &targets { - info!("Building for target: {t:?}"); - example_build(&cargoarg, t, &examples_to_run)?; - } + info!("Building for backend: {backend:?}"); + example_build(&cargoarg, backend, &examples_to_run)?; } Commands::ExampleCheck => { - debug!("Checking on target(s): {targets:?}"); - for t in &targets { - info!("Checking on target: {t:?}"); - example_check(&cargoarg, t, &examples_to_run)?; - } + info!("Checking on backend: {backend:?}"); + example_check(&cargoarg, backend, &examples_to_run)?; } Commands::Build(args) => { - debug!("Building for target(s): {targets:?}"); - for t in &targets { - info!("Building for target: {t:?}"); - cargo_build(&cargoarg, &args, t)?; - } + info!("Building for backend: {backend:?}"); + cargo_build(&cargoarg, &args, backend)?; } Commands::Check(args) => { - debug!("Checking on target(s): {targets:?}"); - for t in &targets { - info!("Checking on target: {t:?}"); - cargo_check(&cargoarg, &args, t)?; - } + info!("Checking on backend: {backend:?}"); + cargo_check(&cargoarg, &args, backend)?; } Commands::Clippy(args) => { - debug!("Clippy on target(s): {targets:?}"); - for t in &targets { - info!("Running clippy on target: {t:?}"); - cargo_clippy(&cargoarg, &args, t)?; - } + info!("Running clippy on backend: {backend:?}"); + cargo_clippy(&cargoarg, &args, backend)?; } } Ok(()) } -fn cargo_build(cargoarg: &Option<&str>, package: &Package, target: &str) -> anyhow::Result<()> { +fn cargo_build( + cargoarg: &Option<&str>, + package: &Package, + backend: Backends, +) -> anyhow::Result<()> { command_parser( &CargoCommand::Build { cargoarg, package: package_filter(package), - target, + target: backend.to_target(), features: None, mode: BuildMode::Release, }, @@ -389,12 +379,16 @@ fn cargo_build(cargoarg: &Option<&str>, package: &Package, target: &str) -> anyh Ok(()) } -fn cargo_check(cargoarg: &Option<&str>, package: &Package, target: &str) -> anyhow::Result<()> { +fn cargo_check( + cargoarg: &Option<&str>, + package: &Package, + backend: Backends, +) -> anyhow::Result<()> { command_parser( &CargoCommand::Check { cargoarg, package: package_filter(package), - target, + target: backend.to_target(), features: None, }, false, @@ -402,12 +396,16 @@ fn cargo_check(cargoarg: &Option<&str>, package: &Package, target: &str) -> anyh Ok(()) } -fn cargo_clippy(cargoarg: &Option<&str>, package: &Package, target: &str) -> anyhow::Result<()> { +fn cargo_clippy( + cargoarg: &Option<&str>, + package: &Package, + backend: Backends, +) -> anyhow::Result<()> { command_parser( &CargoCommand::Clippy { cargoarg, package: package_filter(package), - target, + target: backend.to_target(), features: None, }, false, @@ -417,16 +415,19 @@ fn cargo_clippy(cargoarg: &Option<&str>, package: &Package, target: &str) -> any fn run_test( cargoarg: &Option<&str>, - target: &str, + backend: Backends, 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, - features: DEFAULT_FEATURES, + target: backend.to_target(), + features, mode: BuildMode::Release, }; if let Err(err) = command_parser(&cmd, false) { @@ -436,8 +437,8 @@ fn run_test( let cmd = CargoCommand::Qemu { cargoarg, example, - target, - features: DEFAULT_FEATURES, + target: backend.to_target(), + features, mode: BuildMode::Release, }; @@ -448,13 +449,20 @@ fn run_test( Ok(()) } -fn example_check(cargoarg: &Option<&str>, target: &str, examples: &[String]) -> anyhow::Result<()> { +fn example_check( + cargoarg: &Option<&str>, + 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 cmd = CargoCommand::ExampleCheck { cargoarg, example, - target, - features: DEFAULT_FEATURES, + target: backend.to_target(), + features, mode: BuildMode::Release, }; @@ -466,13 +474,20 @@ fn example_check(cargoarg: &Option<&str>, target: &str, examples: &[String]) -> Ok(()) } -fn example_build(cargoarg: &Option<&str>, target: &str, examples: &[String]) -> anyhow::Result<()> { +fn example_build( + cargoarg: &Option<&str>, + 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 cmd = CargoCommand::ExampleBuild { cargoarg, example, - target, - features: DEFAULT_FEATURES, + target: backend.to_target(), + features, mode: BuildMode::Release, }; @@ -486,17 +501,20 @@ fn example_build(cargoarg: &Option<&str>, target: &str, examples: &[String]) -> fn build_and_check_size( cargoarg: &Option<&str>, - target: &str, + backend: Backends, examples: &[String], size_arguments: &Option, ) -> 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, - features: DEFAULT_FEATURES, + target: backend.to_target(), + features, mode: BuildMode::Release, }; if let Err(err) = command_parser(&cmd, false) { @@ -506,8 +524,8 @@ fn build_and_check_size( let cmd = CargoCommand::ExampleSize { cargoarg, example, - target, - features: DEFAULT_FEATURES, + target: backend.to_target(), + features, mode: BuildMode::Release, arguments: size_arguments.clone(), }; -- cgit v1.2.3 From 4442c4692634c90ba60653d42d72f9f259ae1a16 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Mon, 20 Feb 2023 20:56:18 +0100 Subject: Update backend features to be more clear --- xtask/src/main.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/main.rs b/xtask/src/main.rs index b270a44..9ff0ae2 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -55,10 +55,10 @@ impl Backends { fn to_rtic_feature(&self) -> &str { match self { - Backends::Thumbv6 => "thumbv6", - Backends::Thumbv7 => "thumbv7", - Backends::Thumbv8Base => "thumbv8_base", - Backends::Thumbv8Main => "thumbv8_main", + Backends::Thumbv6 => "thumbv6-backend", + Backends::Thumbv7 => "thumbv7-backend", + Backends::Thumbv8Base => "thumbv8base-backend", + Backends::Thumbv8Main => "thumbv8main-backend", } } } -- cgit v1.2.3 From aa30d1d2516586841d2a353db064bfc2839343fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Thu, 23 Feb 2023 19:34:52 +0100 Subject: xtask: Default backend needs no argument Propagate features for check and build --- xtask/src/main.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 9ff0ae2..f6d8975 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -69,7 +69,7 @@ impl Backends { struct Cli { /// For which backend to build #[arg(value_enum, short, long)] - backend: Backends, + backend: Option, /// List of comma separated examples to include, all others are excluded /// @@ -254,7 +254,11 @@ fn main() -> anyhow::Result<()> { trace!("default logging level: {0}", cli.verbose); - let backend = cli.backend; + let backend = if let Some(backend) = cli.backend { + backend + } else { + Backends::default() + }; let example = cli.example; let exampleexclude = cli.exampleexclude; @@ -366,12 +370,14 @@ fn cargo_build( package: &Package, backend: Backends, ) -> anyhow::Result<()> { + let s = format!("{},{}", DEFAULT_FEATURES, backend.to_rtic_feature()); + let features: Option<&str> = Some(&s); command_parser( &CargoCommand::Build { cargoarg, package: package_filter(package), target: backend.to_target(), - features: None, + features, mode: BuildMode::Release, }, false, @@ -384,12 +390,14 @@ fn cargo_check( package: &Package, backend: Backends, ) -> anyhow::Result<()> { + let s = format!("{},{}", DEFAULT_FEATURES, backend.to_rtic_feature()); + let features: Option<&str> = Some(&s); command_parser( &CargoCommand::Check { cargoarg, package: package_filter(package), target: backend.to_target(), - features: None, + features, }, false, )?; -- cgit v1.2.3 From 18c843b5509b76a661dbf141da7cb900401f5074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Fri, 24 Feb 2023 00:10:01 +0100 Subject: xtask: Add format and format-check --- xtask/src/command.rs | 28 +++++++++++++++++++++++++++- xtask/src/main.rs | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) (limited to 'xtask/src') diff --git a/xtask/src/command.rs b/xtask/src/command.rs index d894fae..b1f885c 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -61,6 +61,11 @@ pub enum CargoCommand<'a> { target: &'a str, features: Option<&'a str>, }, + Format { + cargoarg: &'a Option<&'a str>, + package: Vec, + check_only: bool, + }, ExampleSize { cargoarg: &'a Option<&'a str>, example: &'a str, @@ -79,8 +84,8 @@ impl<'a> CargoCommand<'a> { CargoCommand::ExampleBuild { .. } | CargoCommand::Build { .. } => "build", CargoCommand::ExampleSize { .. } => "size", CargoCommand::Clippy { .. } => "clippy", + CargoCommand::Format { .. } => "fmt", // TODO - // CargoCommand::Fmt { .. } => "fmt", // CargoCommand::Test { .. } => "test", // CargoCommand::Doc { .. } => "doc", } @@ -203,6 +208,27 @@ impl<'a> CargoCommand<'a> { } args } + CargoCommand::Format { + cargoarg, + package, + check_only, + } => { + let mut args = vec!["+nightly", self.name()]; + if let Some(cargoarg) = cargoarg { + args.extend_from_slice(&[cargoarg]); + } + + if !package.is_empty() { + for package in package { + args.extend_from_slice(&["--package", package]); + } + } + if *check_only { + args.extend_from_slice(&["--check"]); + } + + args + } CargoCommand::ExampleBuild { cargoarg, example, diff --git a/xtask/src/main.rs b/xtask/src/main.rs index f6d8975..2191384 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -136,6 +136,12 @@ enum Commands { /// Check all packages Check(Package), + /// Check formatting + FormatCheck(Package), + + /// Format code + Format(Package), + /// Run clippy Clippy(Package), } @@ -360,6 +366,16 @@ fn main() -> anyhow::Result<()> { info!("Running clippy on backend: {backend:?}"); cargo_clippy(&cargoarg, &args, backend)?; } + Commands::FormatCheck(args) => { + info!("Running cargo fmt: {args:?}"); + let check_only = true; + cargo_format(&cargoarg, &args, check_only)?; + } + Commands::Format(args) => { + info!("Running cargo fmt --check: {args:?}"); + let check_only = false; + cargo_format(&cargoarg, &args, check_only)?; + } } Ok(()) @@ -421,6 +437,22 @@ fn cargo_clippy( Ok(()) } +fn cargo_format( + cargoarg: &Option<&str>, + package: &Package, + check_only: bool, +) -> anyhow::Result<()> { + command_parser( + &CargoCommand::Format { + cargoarg, + package: package_filter(package), + check_only, + }, + false, + )?; + Ok(()) +} + fn run_test( cargoarg: &Option<&str>, backend: Backends, @@ -621,6 +653,7 @@ fn command_parser(command: &CargoCommand, overwrite: bool) -> anyhow::Result<()> | CargoCommand::Build { .. } | CargoCommand::Check { .. } | CargoCommand::Clippy { .. } + | CargoCommand::Format { .. } | CargoCommand::ExampleSize { .. } => { let cargo_result = run_command(command)?; if let Some(exit_code) = cargo_result.exit_status.code() { -- cgit v1.2.3 From bb8621f2d71edfda5d901f7a066beb5a15d7fdfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Fri, 24 Feb 2023 01:05:21 +0100 Subject: xtask: Do not add rtic features to all workspace crates --- xtask/src/main.rs | 112 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 80 insertions(+), 32 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 2191384..b042b64 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -386,18 +386,34 @@ fn cargo_build( package: &Package, backend: Backends, ) -> anyhow::Result<()> { - let s = format!("{},{}", DEFAULT_FEATURES, backend.to_rtic_feature()); - let features: Option<&str> = Some(&s); - command_parser( - &CargoCommand::Build { - cargoarg, - package: package_filter(package), - target: backend.to_target(), - features, - mode: BuildMode::Release, - }, - false, - )?; + 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::Build { + cargoarg, + package: packages_to_check, + target: backend.to_target(), + features, + mode: BuildMode::Release, + }, + false, + )?; + } else { + command_parser( + &CargoCommand::Build { + cargoarg, + package: package_filter(package), + target: backend.to_target(), + features: None, + mode: BuildMode::Release, + }, + false, + )?; + } Ok(()) } @@ -406,17 +422,32 @@ fn cargo_check( package: &Package, backend: Backends, ) -> anyhow::Result<()> { - let s = format!("{},{}", DEFAULT_FEATURES, backend.to_rtic_feature()); - let features: Option<&str> = Some(&s); - command_parser( - &CargoCommand::Check { - cargoarg, - package: package_filter(package), - target: backend.to_target(), - features, - }, - false, - )?; + 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::Check { + cargoarg, + package: package_filter(package), + target: backend.to_target(), + features, + }, + false, + )?; + } else { + command_parser( + &CargoCommand::Check { + cargoarg, + package: package_filter(package), + target: backend.to_target(), + features: None, + }, + false, + )?; + } Ok(()) } @@ -425,15 +456,32 @@ fn cargo_clippy( package: &Package, backend: Backends, ) -> anyhow::Result<()> { - command_parser( - &CargoCommand::Clippy { - cargoarg, - package: package_filter(package), - target: backend.to_target(), - features: None, - }, - false, - )?; + 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, + )?; + } Ok(()) } -- cgit v1.2.3 From a73a8d63cf9fc08bddb82d1e82cec7c40949edc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Fri, 24 Feb 2023 22:56:36 +0100 Subject: xtask: Add docs building --- xtask/src/command.rs | 19 ++++++++++++++++++- xtask/src/main.rs | 16 ++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) (limited to 'xtask/src') diff --git a/xtask/src/command.rs b/xtask/src/command.rs index b1f885c..6fce1c9 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -66,6 +66,10 @@ pub enum CargoCommand<'a> { package: Vec, check_only: bool, }, + Doc { + cargoarg: &'a Option<&'a str>, + features: Option<&'a str>, + }, ExampleSize { cargoarg: &'a Option<&'a str>, example: &'a str, @@ -85,9 +89,9 @@ impl<'a> CargoCommand<'a> { CargoCommand::ExampleSize { .. } => "size", CargoCommand::Clippy { .. } => "clippy", CargoCommand::Format { .. } => "fmt", + CargoCommand::Doc { .. } => "doc", // TODO // CargoCommand::Test { .. } => "test", - // CargoCommand::Doc { .. } => "doc", } } @@ -208,6 +212,19 @@ impl<'a> CargoCommand<'a> { } args } + CargoCommand::Doc { cargoarg, features } => { + let mut args = vec!["+nightly"]; + if let Some(cargoarg) = cargoarg { + args.extend_from_slice(&[cargoarg]); + } + + args.extend_from_slice(&[self.name()]); + + if let Some(feature) = features { + args.extend_from_slice(&["--features", feature]); + } + args + } CargoCommand::Format { cargoarg, package, diff --git a/xtask/src/main.rs b/xtask/src/main.rs index b042b64..62cfeaf 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -144,6 +144,9 @@ enum Commands { /// Run clippy Clippy(Package), + + /// Build docs + Doc, } #[derive(Args, Debug)] @@ -366,6 +369,10 @@ fn main() -> anyhow::Result<()> { info!("Running clippy on backend: {backend:?}"); cargo_clippy(&cargoarg, &args, backend)?; } + Commands::Doc => { + info!("Running cargo doc on backend: {backend:?}"); + cargo_doc(&cargoarg, backend)?; + } Commands::FormatCheck(args) => { info!("Running cargo fmt: {args:?}"); let check_only = true; @@ -501,6 +508,14 @@ fn cargo_format( Ok(()) } +fn cargo_doc(cargoarg: &Option<&str>, backend: Backends) -> anyhow::Result<()> { + let s = format!("{}", backend.to_rtic_feature()); + let features: Option<&str> = Some(&s); + + command_parser(&CargoCommand::Doc { cargoarg, features }, false)?; + Ok(()) +} + fn run_test( cargoarg: &Option<&str>, backend: Backends, @@ -701,6 +716,7 @@ fn command_parser(command: &CargoCommand, overwrite: bool) -> anyhow::Result<()> | CargoCommand::Build { .. } | CargoCommand::Check { .. } | CargoCommand::Clippy { .. } + | CargoCommand::Doc { .. } | CargoCommand::Format { .. } | CargoCommand::ExampleSize { .. } => { let cargo_result = run_command(command)?; -- cgit v1.2.3 From ff49889890c14599f7581d5bea58bcd6c2ed01fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Fri, 24 Feb 2023 23:14:11 +0100 Subject: xtask: Reorder commands --- xtask/src/command.rs | 5 +++ xtask/src/main.rs | 106 ++++++++++++++++++++++++++------------------------- 2 files changed, 59 insertions(+), 52 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/command.rs b/xtask/src/command.rs index 6fce1c9..4cf387f 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -54,6 +54,7 @@ pub enum CargoCommand<'a> { package: Vec, target: &'a str, features: Option<&'a str>, + mode: BuildMode, }, Clippy { cargoarg: &'a Option<&'a str>, @@ -172,6 +173,7 @@ impl<'a> CargoCommand<'a> { package, target, features, + mode, } => { let mut args = vec!["+nightly"]; if let Some(cargoarg) = cargoarg { @@ -187,6 +189,9 @@ impl<'a> CargoCommand<'a> { if let Some(feature) = features { args.extend_from_slice(&["--features", feature]); } + if let Some(flag) = mode.to_flag() { + args.push(flag); + } args } CargoCommand::Clippy { diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 62cfeaf..23f4242 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -67,7 +67,7 @@ impl Backends { #[command(author, version, about, long_about = None)] /// RTIC xtask powered testing toolbox struct Cli { - /// For which backend to build + /// For which backend to build (defaults to thumbv7) #[arg(value_enum, short, long)] backend: Option, @@ -100,6 +100,27 @@ struct Cli { #[derive(Debug, Subcommand)] enum Commands { + /// Check formatting + FormatCheck(Package), + + /// Format code + Format(Package), + + /// Run clippy + Clippy(Package), + + /// Check all packages + Check(Package), + + /// Build all packages + Build(Package), + + /// Check all examples + ExampleCheck, + + /// Build all examples + ExampleBuild, + /// Run `cargo size` on selected or all examples /// /// To pass options to `cargo size`, add `--` and then the following @@ -124,27 +145,6 @@ enum Commands { /// Requires that an ARM target is selected Run(QemuAndRun), - /// Build all examples - ExampleBuild, - - /// Check all packages - ExampleCheck, - - /// Build all examples - Build(Package), - - /// Check all packages - Check(Package), - - /// Check formatting - FormatCheck(Package), - - /// Format code - Format(Package), - - /// Run clippy - Clippy(Package), - /// Build docs Doc, } @@ -329,6 +329,36 @@ fn main() -> anyhow::Result<()> { }; match cli.command { + Commands::FormatCheck(args) => { + info!("Running cargo fmt: {args:?}"); + let check_only = true; + cargo_format(&cargoarg, &args, check_only)?; + } + Commands::Format(args) => { + info!("Running cargo fmt --check: {args:?}"); + let check_only = false; + cargo_format(&cargoarg, &args, check_only)?; + } + Commands::Clippy(args) => { + info!("Running clippy on backend: {backend:?}"); + cargo_clippy(&cargoarg, &args, backend)?; + } + Commands::Check(args) => { + info!("Checking on backend: {backend:?}"); + cargo_check(&cargoarg, &args, backend)?; + } + Commands::Build(args) => { + info!("Building for backend: {backend:?}"); + cargo_build(&cargoarg, &args, backend)?; + } + Commands::ExampleCheck => { + info!("Checking on backend: {backend:?}"); + example_check(&cargoarg, backend, &examples_to_run)?; + } + Commands::ExampleBuild => { + info!("Building for backend: {backend:?}"); + example_build(&cargoarg, backend, &examples_to_run)?; + } Commands::Size(arguments) => { // x86_64 target not valid info!("Measuring for backend: {backend:?}"); @@ -349,40 +379,10 @@ fn main() -> anyhow::Result<()> { args.overwrite_expected, )?; } - Commands::ExampleBuild => { - info!("Building for backend: {backend:?}"); - example_build(&cargoarg, backend, &examples_to_run)?; - } - Commands::ExampleCheck => { - info!("Checking on backend: {backend:?}"); - example_check(&cargoarg, backend, &examples_to_run)?; - } - Commands::Build(args) => { - info!("Building for backend: {backend:?}"); - cargo_build(&cargoarg, &args, backend)?; - } - Commands::Check(args) => { - info!("Checking on backend: {backend:?}"); - cargo_check(&cargoarg, &args, backend)?; - } - Commands::Clippy(args) => { - info!("Running clippy on backend: {backend:?}"); - cargo_clippy(&cargoarg, &args, backend)?; - } Commands::Doc => { info!("Running cargo doc on backend: {backend:?}"); cargo_doc(&cargoarg, backend)?; } - Commands::FormatCheck(args) => { - info!("Running cargo fmt: {args:?}"); - let check_only = true; - cargo_format(&cargoarg, &args, check_only)?; - } - Commands::Format(args) => { - info!("Running cargo fmt --check: {args:?}"); - let check_only = false; - cargo_format(&cargoarg, &args, check_only)?; - } } Ok(()) @@ -441,6 +441,7 @@ fn cargo_check( package: package_filter(package), target: backend.to_target(), features, + mode: BuildMode::Release, }, false, )?; @@ -451,6 +452,7 @@ fn cargo_check( package: package_filter(package), target: backend.to_target(), features: None, + mode: BuildMode::Release, }, false, )?; -- cgit v1.2.3 From 91be97d33ffe557b400a1f01d93f2fbd4e733552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Fri, 24 Feb 2023 23:31:49 +0100 Subject: xtask: Rename cargoarg to cargologlevel --- xtask/src/main.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 23f4242..c993224 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -315,7 +315,7 @@ fn main() -> anyhow::Result<()> { init_build_dir()?; #[allow(clippy::if_same_then_else)] - let cargoarg = if log_enabled!(Level::Trace) { + let cargologlevel = if log_enabled!(Level::Trace) { Some("-v") } else if log_enabled!(Level::Debug) { None @@ -332,38 +332,38 @@ fn main() -> anyhow::Result<()> { Commands::FormatCheck(args) => { info!("Running cargo fmt: {args:?}"); let check_only = true; - cargo_format(&cargoarg, &args, check_only)?; + cargo_format(&cargologlevel, &args, check_only)?; } Commands::Format(args) => { info!("Running cargo fmt --check: {args:?}"); let check_only = false; - cargo_format(&cargoarg, &args, check_only)?; + cargo_format(&cargologlevel, &args, check_only)?; } Commands::Clippy(args) => { info!("Running clippy on backend: {backend:?}"); - cargo_clippy(&cargoarg, &args, backend)?; + cargo_clippy(&cargologlevel, &args, backend)?; } Commands::Check(args) => { info!("Checking on backend: {backend:?}"); - cargo_check(&cargoarg, &args, backend)?; + cargo(&cli.command, &cargologlevel, &args, backend)?; } Commands::Build(args) => { info!("Building for backend: {backend:?}"); - cargo_build(&cargoarg, &args, backend)?; + cargo_build(&cargologlevel, &args, backend)?; } Commands::ExampleCheck => { info!("Checking on backend: {backend:?}"); - example_check(&cargoarg, backend, &examples_to_run)?; + example_check(&cargologlevel, backend, &examples_to_run)?; } Commands::ExampleBuild => { info!("Building for backend: {backend:?}"); - example_build(&cargoarg, backend, &examples_to_run)?; + example_build(&cargologlevel, backend, &examples_to_run)?; } Commands::Size(arguments) => { // x86_64 target not valid info!("Measuring for backend: {backend:?}"); build_and_check_size( - &cargoarg, + &cargologlevel, backend, &examples_to_run, &arguments.sizearguments, @@ -373,7 +373,7 @@ fn main() -> anyhow::Result<()> { // x86_64 target not valid info!("Testing for backend: {backend:?}"); run_test( - &cargoarg, + &cargologlevel, backend, &examples_to_run, args.overwrite_expected, @@ -381,7 +381,7 @@ fn main() -> anyhow::Result<()> { } Commands::Doc => { info!("Running cargo doc on backend: {backend:?}"); - cargo_doc(&cargoarg, backend)?; + cargo_doc(&cargologlevel, backend)?; } } -- cgit v1.2.3 From 8b3aa7f346f87a75c6fa2b5240edebe62b10a811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Sat, 25 Feb 2023 00:11:12 +0100 Subject: xtask: Cleanup check and build --- xtask/src/main.rs | 169 ++++++++++++++++++++++-------------------------------- 1 file changed, 68 insertions(+), 101 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/main.rs b/xtask/src/main.rs index c993224..2c37f82 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -63,6 +63,13 @@ impl Backends { } } +#[derive(Copy, Clone, Default, Debug)] +enum BuildOrCheck { + #[default] + Check, + Build, +} + #[derive(Parser)] #[command(author, version, about, long_about = None)] /// RTIC xtask powered testing toolbox @@ -345,19 +352,29 @@ fn main() -> anyhow::Result<()> { } Commands::Check(args) => { info!("Checking on backend: {backend:?}"); - cargo(&cli.command, &cargologlevel, &args, backend)?; + cargo(BuildOrCheck::Check, &cargologlevel, &args, backend)?; } Commands::Build(args) => { info!("Building for backend: {backend:?}"); - cargo_build(&cargologlevel, &args, backend)?; + cargo(BuildOrCheck::Build, &cargologlevel, &args, backend)?; } Commands::ExampleCheck => { info!("Checking on backend: {backend:?}"); - example_check(&cargologlevel, backend, &examples_to_run)?; + cargo_example( + BuildOrCheck::Check, + &cargologlevel, + backend, + &examples_to_run, + )?; } Commands::ExampleBuild => { info!("Building for backend: {backend:?}"); - example_build(&cargologlevel, backend, &examples_to_run)?; + cargo_example( + BuildOrCheck::Build, + &cargologlevel, + backend, + &examples_to_run, + )?; } Commands::Size(arguments) => { // x86_64 target not valid @@ -388,75 +405,74 @@ fn main() -> anyhow::Result<()> { Ok(()) } -fn cargo_build( +fn cargo( + operation: BuildOrCheck, cargoarg: &Option<&str>, package: &Package, 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::Build { - cargoarg, - package: packages_to_check, - target: backend.to_target(), - features, - mode: BuildMode::Release, - }, - false, - )?; + // 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 { - command_parser( - &CargoCommand::Build { - cargoarg, - package: package_filter(package), - target: backend.to_target(), - features: None, - mode: BuildMode::Release, - }, - false, - )?; - } + None + }; + + let command = match operation { + BuildOrCheck::Check => CargoCommand::Check { + cargoarg, + package: packages, + target: backend.to_target(), + features, + mode: BuildMode::Release, + }, + BuildOrCheck::Build => CargoCommand::Build { + cargoarg, + package: packages, + target: backend.to_target(), + features, + mode: BuildMode::Release, + }, + }; + command_parser(&command, false)?; Ok(()) } -fn cargo_check( +fn cargo_example( + operation: BuildOrCheck, cargoarg: &Option<&str>, - package: &Package, backend: Backends, + examples: &[String], ) -> 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); + let s = format!("{},{}", DEFAULT_FEATURES, backend.to_rtic_feature()); + let features: Option<&str> = Some(&s); - command_parser( - &CargoCommand::Check { + examples.into_par_iter().for_each(|example| { + let command = match operation { + BuildOrCheck::Check => CargoCommand::ExampleCheck { cargoarg, - package: package_filter(package), + example, target: backend.to_target(), features, mode: BuildMode::Release, }, - false, - )?; - } else { - command_parser( - &CargoCommand::Check { + BuildOrCheck::Build => CargoCommand::ExampleBuild { cargoarg, - package: package_filter(package), + example, target: backend.to_target(), - features: None, + features, mode: BuildMode::Release, }, - false, - )?; - } + }; + + if let Err(err) = command_parser(&command, false) { + error!("{err}"); + } + }); + Ok(()) } @@ -554,55 +570,6 @@ fn run_test( Ok(()) } -fn example_check( - cargoarg: &Option<&str>, - 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 cmd = CargoCommand::ExampleCheck { - cargoarg, - example, - target: backend.to_target(), - features, - mode: BuildMode::Release, - }; - - if let Err(err) = command_parser(&cmd, false) { - error!("{err}"); - } - }); - - Ok(()) -} - -fn example_build( - cargoarg: &Option<&str>, - 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 cmd = CargoCommand::ExampleBuild { - cargoarg, - example, - target: backend.to_target(), - features, - mode: BuildMode::Release, - }; - - if let Err(err) = command_parser(&cmd, false) { - error!("{err}"); - } - }); - - Ok(()) -} fn build_and_check_size( cargoarg: &Option<&str>, -- cgit v1.2.3 From 14457da4f831c57e7a2b1c54e1c37adb8354c8d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Sat, 25 Feb 2023 00:28:45 +0100 Subject: xtask: Add book building --- xtask/src/command.rs | 37 +++++++++++++++++++++++++++++++++---- xtask/src/main.rs | 24 +++++++++++++++++++++--- 2 files changed, 54 insertions(+), 7 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/command.rs b/xtask/src/command.rs index 4cf387f..e43c936 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -71,6 +71,9 @@ pub enum CargoCommand<'a> { cargoarg: &'a Option<&'a str>, features: Option<&'a str>, }, + Book { + mdbookarg: &'a Option<&'a str>, + }, ExampleSize { cargoarg: &'a Option<&'a str>, example: &'a str, @@ -91,6 +94,24 @@ impl<'a> CargoCommand<'a> { CargoCommand::Clippy { .. } => "clippy", CargoCommand::Format { .. } => "fmt", CargoCommand::Doc { .. } => "doc", + CargoCommand::Book { .. } => "build", + // TODO + // CargoCommand::Test { .. } => "test", + } + } + pub fn command(&self) -> &str { + match self { + CargoCommand::Run { .. } + | CargoCommand::Qemu { .. } + | CargoCommand::ExampleCheck { .. } + | CargoCommand::Check { .. } + | CargoCommand::ExampleBuild { .. } + | CargoCommand::Build { .. } + | CargoCommand::ExampleSize { .. } + | CargoCommand::Clippy { .. } + | CargoCommand::Format { .. } + | CargoCommand::Doc { .. } => "cargo", + CargoCommand::Book { .. } => "mdbook", // TODO // CargoCommand::Test { .. } => "test", } @@ -230,6 +251,18 @@ impl<'a> CargoCommand<'a> { } args } + CargoCommand::Book { mdbookarg } => { + let mut args = vec![]; + + args.extend_from_slice(&[self.name()]); + + if let Some(arg) = mdbookarg { + args.extend_from_slice(&[arg]); + } + + args.extend_from_slice(&["book/en"]); + args + } CargoCommand::Format { cargoarg, package, @@ -324,10 +357,6 @@ impl<'a> CargoCommand<'a> { } } } - - pub fn command(&self) -> &str { - "cargo" - } } impl BuildMode { diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 2c37f82..d881224 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -154,6 +154,9 @@ enum Commands { /// Build docs Doc, + + /// Build books with mdbook + Book, } #[derive(Args, Debug)] @@ -400,6 +403,10 @@ fn main() -> anyhow::Result<()> { info!("Running cargo doc on backend: {backend:?}"); cargo_doc(&cargologlevel, backend)?; } + Commands::Book => { + info!("Running mdbook build"); + cargo_book(&cargologlevel)?; + } } Ok(()) @@ -534,6 +541,16 @@ fn cargo_doc(cargoarg: &Option<&str>, backend: Backends) -> anyhow::Result<()> { Ok(()) } +fn cargo_book(cargoarg: &Option<&str>) -> anyhow::Result<()> { + command_parser( + &CargoCommand::Book { + mdbookarg: cargoarg, + }, + false, + )?; + Ok(()) +} + fn run_test( cargoarg: &Option<&str>, backend: Backends, @@ -680,13 +697,14 @@ fn command_parser(command: &CargoCommand, overwrite: bool) -> anyhow::Result<()> } Ok(()) } - CargoCommand::ExampleBuild { .. } + CargoCommand::Format { .. } | CargoCommand::ExampleCheck { .. } - | CargoCommand::Build { .. } + | CargoCommand::ExampleBuild { .. } | CargoCommand::Check { .. } + | CargoCommand::Build { .. } | CargoCommand::Clippy { .. } | CargoCommand::Doc { .. } - | CargoCommand::Format { .. } + | CargoCommand::Book { .. } | CargoCommand::ExampleSize { .. } => { let cargo_result = run_command(command)?; if let Some(exit_code) = cargo_result.exit_status.code() { -- cgit v1.2.3 From a575266ec2da56fb202de35948650c7f11a2909d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Tue, 28 Feb 2023 23:55:02 +0100 Subject: xtask: Add tests, clean a bit --- xtask/src/command.rs | 86 +++++++++------ xtask/src/main.rs | 307 +++++++++++++++++++++++++++++++++++---------------- 2 files changed, 264 insertions(+), 129 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/command.rs b/xtask/src/command.rs index e43c936..9f87522 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -1,4 +1,4 @@ -use crate::{debug, RunResult, Sizearguments, TestRunError}; +use crate::{debug, Package, RunResult, Sizearguments, TestRunError}; use core::fmt; use os_pipe::pipe; use std::{fs::File, io::Read, process::Command}; @@ -18,58 +18,63 @@ pub enum CargoCommand<'a> { cargoarg: &'a Option<&'a str>, example: &'a str, target: &'a str, - features: Option<&'a str>, + features: Option, mode: BuildMode, }, Qemu { cargoarg: &'a Option<&'a str>, example: &'a str, target: &'a str, - features: Option<&'a str>, + features: Option, mode: BuildMode, }, ExampleBuild { cargoarg: &'a Option<&'a str>, example: &'a str, target: &'a str, - features: Option<&'a str>, + features: Option, mode: BuildMode, }, ExampleCheck { cargoarg: &'a Option<&'a str>, example: &'a str, target: &'a str, - features: Option<&'a str>, + features: Option, mode: BuildMode, }, Build { cargoarg: &'a Option<&'a str>, - package: Vec, + package: Option, target: &'a str, - features: Option<&'a str>, + features: Option, mode: BuildMode, }, Check { cargoarg: &'a Option<&'a str>, - package: Vec, + package: Option, target: &'a str, - features: Option<&'a str>, + features: Option, mode: BuildMode, }, Clippy { cargoarg: &'a Option<&'a str>, - package: Vec, + package: Option, target: &'a str, - features: Option<&'a str>, + features: Option, }, Format { cargoarg: &'a Option<&'a str>, - package: Vec, + package: Option, check_only: bool, }, Doc { cargoarg: &'a Option<&'a str>, - features: Option<&'a str>, + features: Option, + }, + Test { + package: Option, + features: Option, + test: Option, }, Book { mdbookarg: &'a Option<&'a str>, @@ -78,7 +83,7 @@ pub enum CargoCommand<'a> { cargoarg: &'a Option<&'a str>, example: &'a str, target: &'a str, - features: Option<&'a str>, + features: Option, mode: BuildMode, arguments: Option, }, @@ -95,8 +100,7 @@ impl<'a> CargoCommand<'a> { CargoCommand::Format { .. } => "fmt", CargoCommand::Doc { .. } => "doc", CargoCommand::Book { .. } => "build", - // TODO - // CargoCommand::Test { .. } => "test", + CargoCommand::Test { .. } => "test", } } pub fn command(&self) -> &str { @@ -110,10 +114,9 @@ impl<'a> CargoCommand<'a> { | CargoCommand::ExampleSize { .. } | CargoCommand::Clippy { .. } | CargoCommand::Format { .. } + | CargoCommand::Test { .. } | CargoCommand::Doc { .. } => "cargo", CargoCommand::Book { .. } => "mdbook", - // TODO - // CargoCommand::Test { .. } => "test", } } @@ -175,10 +178,9 @@ impl<'a> CargoCommand<'a> { } args.extend_from_slice(&[self.name(), "--target", target]); - if !package.is_empty() { - for package in package { - args.extend_from_slice(&["--package", package]); - } + + if let Some(package) = package { + args.extend_from_slice(&["--package", package.to_string()]); } if let Some(feature) = features { @@ -201,10 +203,9 @@ impl<'a> CargoCommand<'a> { args.extend_from_slice(&[cargoarg]); } args.extend_from_slice(&[self.name(), "--target", target]); - if !package.is_empty() { - for package in package { - args.extend_from_slice(&["--package", package]); - } + + if let Some(package) = package { + args.extend_from_slice(&["--package", package.to_string()]); } if let Some(feature) = features { @@ -227,10 +228,9 @@ impl<'a> CargoCommand<'a> { } args.extend_from_slice(&[self.name(), "--target", target]); - if !package.is_empty() { - for package in package { - args.extend_from_slice(&["--package", package]); - } + + if let Some(package) = package { + args.extend_from_slice(&["--package", package.to_string()]); } if let Some(feature) = features { @@ -251,6 +251,26 @@ impl<'a> CargoCommand<'a> { } args } + CargoCommand::Test { + package, + features, + test, + } => { + let mut args = vec!["+nightly"]; + args.extend_from_slice(&[self.name()]); + + if let Some(package) = package { + args.extend_from_slice(&["--package", package.to_string()]); + } + + 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 { mdbookarg } => { let mut args = vec![]; @@ -273,10 +293,8 @@ impl<'a> CargoCommand<'a> { args.extend_from_slice(&[cargoarg]); } - if !package.is_empty() { - for package in package { - args.extend_from_slice(&["--package", package]); - } + if let Some(package) = package { + args.extend_from_slice(&["--package", package.to_string()]); } if *check_only { args.extend_from_slice(&["--check"]); 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, + package: Option, } #[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, ) -> 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 { - // TODO Parse Cargo.toml workspace definition instead? - let packages: Vec = [ - "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 { + 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)?; -- cgit v1.2.3 From 512bab17cc52a288dd2e41e39f7b3b0af95e03ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Wed, 1 Mar 2023 00:10:07 +0100 Subject: xtask: Split out arg parsing --- xtask/src/argument_parsing.rs | 253 +++++++++++++++++++++++++++++++++++++++++ xtask/src/command.rs | 10 +- xtask/src/main.rs | 258 +----------------------------------------- 3 files changed, 263 insertions(+), 258 deletions(-) create mode 100644 xtask/src/argument_parsing.rs (limited to 'xtask/src') diff --git a/xtask/src/argument_parsing.rs b/xtask/src/argument_parsing.rs new file mode 100644 index 0000000..bd28492 --- /dev/null +++ b/xtask/src/argument_parsing.rs @@ -0,0 +1,253 @@ +use crate::{command::CargoCommand, ARMV6M, ARMV7M, ARMV8MBASE, ARMV8MMAIN, DEFAULT_FEATURES}; +use clap::{Args, Parser, Subcommand}; +use core::fmt; + +#[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.name()) + } +} + +impl Package { + pub fn name(&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", + } + } +} + +pub struct TestMetadata {} + +impl TestMetadata { + pub 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)] +pub enum Backends { + Thumbv6, + #[default] + Thumbv7, + Thumbv8Base, + Thumbv8Main, +} + +impl Backends { + pub fn to_target(&self) -> &str { + match self { + Backends::Thumbv6 => ARMV6M, + Backends::Thumbv7 => ARMV7M, + Backends::Thumbv8Base => ARMV8MBASE, + Backends::Thumbv8Main => ARMV8MMAIN, + } + } + + pub fn to_rtic_feature(&self) -> &str { + match self { + Backends::Thumbv6 => "thumbv6-backend", + Backends::Thumbv7 => "thumbv7-backend", + Backends::Thumbv8Base => "thumbv8base-backend", + Backends::Thumbv8Main => "thumbv8main-backend", + } + } + pub 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)] +pub enum BuildOrCheck { + #[default] + Check, + Build, +} + +#[derive(Parser)] +#[command(author, version, about, long_about = None)] +/// RTIC xtask powered testing toolbox +pub struct Cli { + /// For which backend to build (defaults to thumbv7) + #[arg(value_enum, short, long)] + pub backend: Option, + + /// List of comma separated examples to include, all others are excluded + /// + /// If omitted all examples are included + /// + /// Example: `cargo xtask --example complex,spawn,init` + /// would include complex, spawn and init + #[arg(short, long, group = "example_group")] + pub example: Option, + + /// List of comma separated examples to exclude, all others are included + /// + /// If omitted all examples are included + /// + /// Example: `cargo xtask --excludeexample complex,spawn,init` + /// would exclude complex, spawn and init + #[arg(long, group = "example_group")] + pub exampleexclude: Option, + + /// Enable more verbose output, repeat up to `-vvv` for even more + #[arg(short, long, action = clap::ArgAction::Count)] + pub verbose: u8, + + /// Subcommand selecting operation + #[command(subcommand)] + pub command: Commands, +} + +#[derive(Debug, Subcommand)] +pub enum Commands { + /// Check formatting + FormatCheck(PackageOpt), + + /// Format code + Format(PackageOpt), + + /// Run clippy + Clippy(PackageOpt), + + /// Check all packages + Check(PackageOpt), + + /// Build all packages + Build(PackageOpt), + + /// Check all examples + ExampleCheck, + + /// Build all examples + ExampleBuild, + + /// Run `cargo size` on selected or all examples + /// + /// To pass options to `cargo size`, add `--` and then the following + /// arguments will be passed on + /// + /// Example: `cargo xtask size -- -A` + Size(Size), + + /// Run examples in QEMU and compare against expected output + /// + /// Example runtime output is matched against `rtic/ci/expected/` + /// + /// Requires that an ARM target is selected + Qemu(QemuAndRun), + + /// Run examples through embedded-ci and compare against expected output + /// + /// unimplemented!() For now TODO, equal to Qemu + /// + /// Example runtime output is matched against `rtic/ci/expected/` + /// + /// Requires that an ARM target is selected + Run(QemuAndRun), + + /// Build docs + Doc, + + /// Run tests + Test(PackageOpt), + + /// Build books with mdbook + Book, +} + +#[derive(Args, Debug)] +/// Restrict to package, or run on whole workspace +pub struct PackageOpt { + /// For which package/workspace member to operate + /// + /// If omitted, work on all + pub package: Option, +} + +#[derive(Args, Debug)] +pub struct QemuAndRun { + /// If expected output is missing or mismatching, recreate the file + /// + /// This overwrites only missing or mismatching + #[arg(long)] + pub overwrite_expected: bool, +} + +#[derive(Debug, Parser)] +pub struct Size { + /// Options to pass to `cargo size` + #[command(subcommand)] + pub sizearguments: Option, +} + +#[derive(Clone, Debug, PartialEq, Parser)] +pub enum Sizearguments { + /// All remaining flags and options + #[command(external_subcommand)] + Other(Vec), +} diff --git a/xtask/src/command.rs b/xtask/src/command.rs index 9f87522..9d22cf6 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -180,7 +180,7 @@ impl<'a> CargoCommand<'a> { args.extend_from_slice(&[self.name(), "--target", target]); if let Some(package) = package { - args.extend_from_slice(&["--package", package.to_string()]); + args.extend_from_slice(&["--package", package.name()]); } if let Some(feature) = features { @@ -205,7 +205,7 @@ impl<'a> CargoCommand<'a> { args.extend_from_slice(&[self.name(), "--target", target]); if let Some(package) = package { - args.extend_from_slice(&["--package", package.to_string()]); + args.extend_from_slice(&["--package", package.name()]); } if let Some(feature) = features { @@ -230,7 +230,7 @@ impl<'a> CargoCommand<'a> { args.extend_from_slice(&[self.name(), "--target", target]); if let Some(package) = package { - args.extend_from_slice(&["--package", package.to_string()]); + args.extend_from_slice(&["--package", package.name()]); } if let Some(feature) = features { @@ -260,7 +260,7 @@ impl<'a> CargoCommand<'a> { args.extend_from_slice(&[self.name()]); if let Some(package) = package { - args.extend_from_slice(&["--package", package.to_string()]); + args.extend_from_slice(&["--package", package.name()]); } if let Some(feature) = features { @@ -294,7 +294,7 @@ impl<'a> CargoCommand<'a> { } if let Some(package) = package { - args.extend_from_slice(&["--package", package.to_string()]); + args.extend_from_slice(&["--package", package.name()]); } if *check_only { args.extend_from_slice(&["--check"]); diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 2daddaa..34d4d0a 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,9 +1,12 @@ +mod argument_parsing; mod build; mod command; use anyhow::bail; -use clap::{Args, Parser, Subcommand}; +use argument_parsing::{Package, Sizearguments, TestMetadata}; +use clap::Parser; use core::fmt; +use diffy::{create_patch, PatchFormatter}; use rayon::prelude::*; use std::{ error::Error, @@ -20,6 +23,7 @@ use env_logger::Env; use log::{debug, error, info, log_enabled, trace, Level}; use crate::{ + argument_parsing::{Backends, BuildOrCheck, Cli, Commands, PackageOpt}, build::init_build_dir, command::{run_command, run_successful, BuildMode, CargoCommand}, }; @@ -33,256 +37,6 @@ 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, - #[default] - Thumbv7, - Thumbv8Base, - Thumbv8Main, -} - -impl Backends { - fn to_target(&self) -> &str { - match self { - Backends::Thumbv6 => ARMV6M, - Backends::Thumbv7 => ARMV7M, - Backends::Thumbv8Base => ARMV8MBASE, - Backends::Thumbv8Main => ARMV8MMAIN, - } - } - - fn to_rtic_feature(&self) -> &str { - match self { - Backends::Thumbv6 => "thumbv6-backend", - Backends::Thumbv7 => "thumbv7-backend", - Backends::Thumbv8Base => "thumbv8base-backend", - 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)] -enum BuildOrCheck { - #[default] - Check, - Build, -} - -#[derive(Parser)] -#[command(author, version, about, long_about = None)] -/// RTIC xtask powered testing toolbox -struct Cli { - /// For which backend to build (defaults to thumbv7) - #[arg(value_enum, short, long)] - backend: Option, - - /// List of comma separated examples to include, all others are excluded - /// - /// If omitted all examples are included - /// - /// Example: `cargo xtask --example complex,spawn,init` - /// would include complex, spawn and init - #[arg(short, long, group = "example_group")] - example: Option, - - /// List of comma separated examples to exclude, all others are included - /// - /// If omitted all examples are included - /// - /// Example: `cargo xtask --excludeexample complex,spawn,init` - /// would exclude complex, spawn and init - #[arg(long, group = "example_group")] - exampleexclude: Option, - - /// Enable more verbose output, repeat up to `-vvv` for even more - #[arg(short, long, action = clap::ArgAction::Count)] - verbose: u8, - - /// Subcommand selecting operation - #[command(subcommand)] - command: Commands, -} - -#[derive(Debug, Subcommand)] -enum Commands { - /// Check formatting - FormatCheck(PackageOpt), - - /// Format code - Format(PackageOpt), - - /// Run clippy - Clippy(PackageOpt), - - /// Check all packages - Check(PackageOpt), - - /// Build all packages - Build(PackageOpt), - - /// Check all examples - ExampleCheck, - - /// Build all examples - ExampleBuild, - - /// Run `cargo size` on selected or all examples - /// - /// To pass options to `cargo size`, add `--` and then the following - /// arguments will be passed on - /// - /// Example: `cargo xtask size -- -A` - Size(Size), - - /// Run examples in QEMU and compare against expected output - /// - /// Example runtime output is matched against `rtic/ci/expected/` - /// - /// Requires that an ARM target is selected - Qemu(QemuAndRun), - - /// Run examples through embedded-ci and compare against expected output - /// - /// unimplemented!() For now TODO, equal to Qemu - /// - /// Example runtime output is matched against `rtic/ci/expected/` - /// - /// Requires that an ARM target is selected - Run(QemuAndRun), - - /// Build docs - Doc, - - /// Run tests - Test(PackageOpt), - - /// Build books with mdbook - Book, -} - -#[derive(Args, Debug)] -/// Restrict to package, or run on whole workspace -struct PackageOpt { - /// For which package/workspace member to operate - /// - /// If omitted, work on all - package: Option, -} - -#[derive(Args, Debug)] -struct QemuAndRun { - /// If expected output is missing or mismatching, recreate the file - /// - /// This overwrites only missing or mismatching - #[arg(long)] - overwrite_expected: bool, -} - -#[derive(Debug, Parser)] -struct Size { - /// Options to pass to `cargo size` - #[command(subcommand)] - sizearguments: Option, -} - -#[derive(Clone, Debug, PartialEq, Parser)] -pub enum Sizearguments { - /// All remaining flags and options - #[command(external_subcommand)] - Other(Vec), -} - #[derive(Debug, Clone)] pub struct RunResult { exit_status: ExitStatus, @@ -298,8 +52,6 @@ pub enum TestRunError { CommandError(RunResult), IncompatibleCommand, } -use diffy::{create_patch, PatchFormatter}; - impl fmt::Display for TestRunError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { -- cgit v1.2.3 From fae15db2163996828c12a7981c1f679b0c7a5cfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Wed, 1 Mar 2023 00:25:05 +0100 Subject: xtask: Split out cargo commands --- xtask/src/cargo_commands.rs | 267 ++++++++++++++++++++++++++++++++++++++++++++ xtask/src/main.rs | 255 ++---------------------------------------- 2 files changed, 274 insertions(+), 248 deletions(-) create mode 100644 xtask/src/cargo_commands.rs (limited to 'xtask/src') diff --git a/xtask/src/cargo_commands.rs b/xtask/src/cargo_commands.rs new file mode 100644 index 0000000..996fa9c --- /dev/null +++ b/xtask/src/cargo_commands.rs @@ -0,0 +1,267 @@ +use crate::{ + argument_parsing::{Backends, BuildOrCheck, Package, PackageOpt, Sizearguments, TestMetadata}, + command::{BuildMode, CargoCommand}, + command_parser, package_feature_extractor, DEFAULT_FEATURES, +}; +use log::error; +use rayon::prelude::*; + +/// Cargo command to either build or check +pub fn cargo( + operation: BuildOrCheck, + cargoarg: &Option<&str>, + package: &PackageOpt, + backend: Backends, +) -> anyhow::Result<()> { + let features = package_feature_extractor(package, backend); + + let command = match operation { + BuildOrCheck::Check => CargoCommand::Check { + cargoarg, + package: package.package, + target: backend.to_target(), + features, + mode: BuildMode::Release, + }, + BuildOrCheck::Build => CargoCommand::Build { + cargoarg, + package: package.package, + target: backend.to_target(), + features, + mode: BuildMode::Release, + }, + }; + command_parser(&command, false)?; + Ok(()) +} + +/// Cargo command to either build or check all examples +/// +/// The examples are in rtic/examples +pub fn cargo_example( + operation: BuildOrCheck, + cargoarg: &Option<&str>, + backend: Backends, + examples: &[String], +) -> anyhow::Result<()> { + 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, + example, + target: backend.to_target(), + features, + mode: BuildMode::Release, + }, + BuildOrCheck::Build => CargoCommand::ExampleBuild { + cargoarg, + example, + target: backend.to_target(), + features, + mode: BuildMode::Release, + }, + }; + + if let Err(err) = command_parser(&command, false) { + error!("{err}"); + } + }); + + Ok(()) +} + +/// Run cargo clippy on selected package +pub fn cargo_clippy( + cargoarg: &Option<&str>, + package: &PackageOpt, + backend: Backends, +) -> anyhow::Result<()> { + let features = package_feature_extractor(package, backend); + command_parser( + &CargoCommand::Clippy { + cargoarg, + package: package.package, + target: backend.to_target(), + features, + }, + false, + )?; + Ok(()) +} + +/// Run cargo fmt on selected package +pub fn cargo_format( + cargoarg: &Option<&str>, + package: &PackageOpt, + check_only: bool, +) -> anyhow::Result<()> { + command_parser( + &CargoCommand::Format { + cargoarg, + package: package.package, + check_only, + }, + false, + )?; + Ok(()) +} + +/// Run cargo doc +pub fn cargo_doc(cargoarg: &Option<&str>, backend: Backends) -> anyhow::Result<()> { + let features = Some(format!( + "{},{}", + DEFAULT_FEATURES, + backend.to_rtic_feature() + )); + + command_parser(&CargoCommand::Doc { cargoarg, features }, false)?; + Ok(()) +} + +/// Run cargo test on the selcted package or all packages +/// +/// If no package is specified, loop through all packages +pub 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(()) +} + +/// Use mdbook to build the book +pub fn cargo_book(cargoarg: &Option<&str>) -> anyhow::Result<()> { + command_parser( + &CargoCommand::Book { + mdbookarg: cargoarg, + }, + false, + )?; + Ok(()) +} + +/// Run examples +/// +/// Supports updating the expected output via the overwrite argument +pub fn run_test( + cargoarg: &Option<&str>, + backend: Backends, + examples: &[String], + overwrite: bool, +) -> anyhow::Result<()> { + examples.into_par_iter().for_each(|example| { + let cmd = CargoCommand::ExampleBuild { + cargoarg: &Some("--quiet"), + example, + target: backend.to_target(), + features: Some(format!( + "{},{}", + DEFAULT_FEATURES, + backend.to_rtic_feature() + )), + mode: BuildMode::Release, + }; + if let Err(err) = command_parser(&cmd, false) { + error!("{err}"); + } + + let cmd = CargoCommand::Qemu { + cargoarg, + example, + target: backend.to_target(), + features: Some(format!( + "{},{}", + DEFAULT_FEATURES, + backend.to_rtic_feature() + )), + mode: BuildMode::Release, + }; + + if let Err(err) = command_parser(&cmd, overwrite) { + error!("{err}"); + } + }); + + Ok(()) +} + +/// Check the binary sizes of examples +pub fn build_and_check_size( + cargoarg: &Option<&str>, + backend: Backends, + examples: &[String], + size_arguments: &Option, +) -> anyhow::Result<()> { + 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: Some(format!( + "{},{}", + DEFAULT_FEATURES, + backend.to_rtic_feature() + )), + mode: BuildMode::Release, + }; + if let Err(err) = command_parser(&cmd, false) { + error!("{err}"); + } + + let cmd = CargoCommand::ExampleSize { + cargoarg, + example, + target: backend.to_target(), + features: Some(format!( + "{},{}", + DEFAULT_FEATURES, + backend.to_rtic_feature() + )), + mode: BuildMode::Release, + arguments: size_arguments.clone(), + }; + if let Err(err) = command_parser(&cmd, false) { + error!("{err}"); + } + }); + + Ok(()) +} diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 34d4d0a..6bf9317 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,13 +1,13 @@ mod argument_parsing; mod build; +mod cargo_commands; mod command; use anyhow::bail; -use argument_parsing::{Package, Sizearguments, TestMetadata}; +use argument_parsing::{Package, Sizearguments}; use clap::Parser; use core::fmt; use diffy::{create_patch, PatchFormatter}; -use rayon::prelude::*; use std::{ error::Error, ffi::OsString, @@ -25,7 +25,11 @@ use log::{debug, error, info, log_enabled, trace, Level}; use crate::{ argument_parsing::{Backends, BuildOrCheck, Cli, Commands, PackageOpt}, build::init_build_dir, - command::{run_command, run_successful, BuildMode, CargoCommand}, + cargo_commands::{ + build_and_check_size, cargo, cargo_book, cargo_clippy, cargo_doc, cargo_example, + cargo_format, cargo_test, run_test, + }, + command::{run_command, run_successful, CargoCommand}, }; // x86_64-unknown-linux-gnu @@ -260,251 +264,6 @@ fn main() -> anyhow::Result<()> { Ok(()) } -fn cargo( - operation: BuildOrCheck, - cargoarg: &Option<&str>, - package: &PackageOpt, - backend: Backends, -) -> anyhow::Result<()> { - let features = package_feature_extractor(package, backend); - - let command = match operation { - BuildOrCheck::Check => CargoCommand::Check { - cargoarg, - package: package.package, - target: backend.to_target(), - features, - mode: BuildMode::Release, - }, - BuildOrCheck::Build => CargoCommand::Build { - cargoarg, - package: package.package, - target: backend.to_target(), - features, - mode: BuildMode::Release, - }, - }; - command_parser(&command, false)?; - Ok(()) -} - -fn cargo_example( - operation: BuildOrCheck, - cargoarg: &Option<&str>, - backend: Backends, - examples: &[String], -) -> anyhow::Result<()> { - 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, - example, - target: backend.to_target(), - features, - mode: BuildMode::Release, - }, - BuildOrCheck::Build => CargoCommand::ExampleBuild { - cargoarg, - example, - target: backend.to_target(), - features, - mode: BuildMode::Release, - }, - }; - - if let Err(err) = command_parser(&command, false) { - error!("{err}"); - } - }); - - Ok(()) -} - -fn cargo_clippy( - cargoarg: &Option<&str>, - package: &PackageOpt, - backend: Backends, -) -> anyhow::Result<()> { - 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: &PackageOpt, - check_only: bool, -) -> anyhow::Result<()> { - command_parser( - &CargoCommand::Format { - cargoarg, - package: package.package, - check_only, - }, - false, - )?; - Ok(()) -} - -fn cargo_doc(cargoarg: &Option<&str>, backend: Backends) -> anyhow::Result<()> { - 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 { - mdbookarg: cargoarg, - }, - false, - )?; - Ok(()) -} - -fn run_test( - cargoarg: &Option<&str>, - backend: Backends, - examples: &[String], - overwrite: bool, -) -> anyhow::Result<()> { - examples.into_par_iter().for_each(|example| { - let cmd = CargoCommand::ExampleBuild { - cargoarg: &Some("--quiet"), - example, - target: backend.to_target(), - features: Some(format!( - "{},{}", - DEFAULT_FEATURES, - backend.to_rtic_feature() - )), - mode: BuildMode::Release, - }; - if let Err(err) = command_parser(&cmd, false) { - error!("{err}"); - } - - let cmd = CargoCommand::Qemu { - cargoarg, - example, - target: backend.to_target(), - features: Some(format!( - "{},{}", - DEFAULT_FEATURES, - backend.to_rtic_feature() - )), - mode: BuildMode::Release, - }; - - if let Err(err) = command_parser(&cmd, overwrite) { - error!("{err}"); - } - }); - - Ok(()) -} - -fn build_and_check_size( - cargoarg: &Option<&str>, - backend: Backends, - examples: &[String], - size_arguments: &Option, -) -> anyhow::Result<()> { - 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: Some(format!( - "{},{}", - DEFAULT_FEATURES, - backend.to_rtic_feature() - )), - mode: BuildMode::Release, - }; - if let Err(err) = command_parser(&cmd, false) { - error!("{err}"); - } - - let cmd = CargoCommand::ExampleSize { - cargoarg, - example, - target: backend.to_target(), - features: Some(format!( - "{},{}", - DEFAULT_FEATURES, - backend.to_rtic_feature() - )), - mode: BuildMode::Release, - arguments: size_arguments.clone(), - }; - if let Err(err) = command_parser(&cmd, false) { - error!("{err}"); - } - }); - - Ok(()) -} - /// Get the features needed given the selected package /// /// Without package specified the features for RTIC are required -- cgit v1.2.3 From c4ee8e8f027a246663514bb5d2d41b21cfd05ed5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Wed, 1 Mar 2023 00:59:06 +0100 Subject: xtask: check and clippy, test without target --- xtask/src/command.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/command.rs b/xtask/src/command.rs index 9d22cf6..b6602ee 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -194,7 +194,7 @@ impl<'a> CargoCommand<'a> { CargoCommand::Check { cargoarg, package, - target, + target: _, features, mode, } => { @@ -202,7 +202,7 @@ impl<'a> CargoCommand<'a> { if let Some(cargoarg) = cargoarg { args.extend_from_slice(&[cargoarg]); } - args.extend_from_slice(&[self.name(), "--target", target]); + args.extend_from_slice(&[self.name()]); if let Some(package) = package { args.extend_from_slice(&["--package", package.name()]); @@ -219,7 +219,7 @@ impl<'a> CargoCommand<'a> { CargoCommand::Clippy { cargoarg, package, - target, + target: _, features, } => { let mut args = vec!["+nightly"]; @@ -227,7 +227,7 @@ impl<'a> CargoCommand<'a> { args.extend_from_slice(&[cargoarg]); } - args.extend_from_slice(&[self.name(), "--target", target]); + args.extend_from_slice(&[self.name()]); if let Some(package) = package { args.extend_from_slice(&["--package", package.name()]); -- cgit v1.2.3 From 39a06368c8f1e6e77c1e838b0a8a39e548c344f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Thu, 2 Mar 2023 19:40:50 +0100 Subject: xtask: rtic-sync --- xtask/src/argument_parsing.rs | 13 +++---------- xtask/src/cargo_commands.rs | 13 ++----------- 2 files changed, 5 insertions(+), 21 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/argument_parsing.rs b/xtask/src/argument_parsing.rs index bd28492..aff464c 100644 --- a/xtask/src/argument_parsing.rs +++ b/xtask/src/argument_parsing.rs @@ -5,11 +5,10 @@ use core::fmt; #[derive(clap::ValueEnum, Copy, Clone, Debug)] pub enum Package { Rtic, - RticArbiter, - RticChannel, RticCommon, RticMacros, RticMonotonics, + RticSync, RticTime, } @@ -23,11 +22,10 @@ impl Package { pub fn name(&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::RticSync => "rtic-sync", Package::RticTime => "rtic-time", } } @@ -55,12 +53,7 @@ impl TestMetadata { 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::RticSync => CargoCommand::Test { package: Some(package), features: Some("testing".to_owned()), test: None, diff --git a/xtask/src/cargo_commands.rs b/xtask/src/cargo_commands.rs index 996fa9c..31250d4 100644 --- a/xtask/src/cargo_commands.rs +++ b/xtask/src/cargo_commands.rs @@ -129,25 +129,16 @@ pub fn cargo_doc(cargoarg: &Option<&str>, backend: Backends) -> anyhow::Result<( /// If no package is specified, loop through all packages pub 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), - }; + let cmd = 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::RticSync, Package::RticTime, ] { let mut error_messages = vec![]; -- cgit v1.2.3 From 3908cbf7e8f3a0e7da7dbe132afd387f227a8a3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Thu, 2 Mar 2023 22:02:19 +0100 Subject: xtask: Allow passing arguments to book and doc --- xtask/src/argument_parsing.rs | 17 +++++++++++------ xtask/src/cargo_commands.rs | 25 ++++++++++++++++++------- xtask/src/command.rs | 34 +++++++++++++++++++++++----------- xtask/src/main.rs | 19 +++++++------------ 4 files changed, 59 insertions(+), 36 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/argument_parsing.rs b/xtask/src/argument_parsing.rs index aff464c..1fc06c1 100644 --- a/xtask/src/argument_parsing.rs +++ b/xtask/src/argument_parsing.rs @@ -185,7 +185,7 @@ pub enum Commands { /// arguments will be passed on /// /// Example: `cargo xtask size -- -A` - Size(Size), + Size(Arg), /// Run examples in QEMU and compare against expected output /// @@ -204,13 +204,18 @@ pub enum Commands { Run(QemuAndRun), /// Build docs - Doc, + /// + /// To pass options to `cargo doc`, add `--` and then the following + /// arguments will be passed on + /// + /// Example: `cargo xtask doc -- --open` + Doc(Arg), /// Run tests Test(PackageOpt), /// Build books with mdbook - Book, + Book(Arg), } #[derive(Args, Debug)] @@ -232,14 +237,14 @@ pub struct QemuAndRun { } #[derive(Debug, Parser)] -pub struct Size { +pub struct Arg { /// Options to pass to `cargo size` #[command(subcommand)] - pub sizearguments: Option, + pub arguments: Option, } #[derive(Clone, Debug, PartialEq, Parser)] -pub enum Sizearguments { +pub enum ExtraArguments { /// All remaining flags and options #[command(external_subcommand)] Other(Vec), diff --git a/xtask/src/cargo_commands.rs b/xtask/src/cargo_commands.rs index 31250d4..f262c9f 100644 --- a/xtask/src/cargo_commands.rs +++ b/xtask/src/cargo_commands.rs @@ -1,5 +1,5 @@ use crate::{ - argument_parsing::{Backends, BuildOrCheck, Package, PackageOpt, Sizearguments, TestMetadata}, + argument_parsing::{Backends, BuildOrCheck, ExtraArguments, Package, PackageOpt, TestMetadata}, command::{BuildMode, CargoCommand}, command_parser, package_feature_extractor, DEFAULT_FEATURES, }; @@ -113,14 +113,25 @@ pub fn cargo_format( } /// Run cargo doc -pub fn cargo_doc(cargoarg: &Option<&str>, backend: Backends) -> anyhow::Result<()> { +pub fn cargo_doc( + cargoarg: &Option<&str>, + backend: Backends, + arguments: &Option, +) -> anyhow::Result<()> { let features = Some(format!( "{},{}", DEFAULT_FEATURES, backend.to_rtic_feature() )); - command_parser(&CargoCommand::Doc { cargoarg, features }, false)?; + command_parser( + &CargoCommand::Doc { + cargoarg, + features, + arguments: arguments.clone(), + }, + false, + )?; Ok(()) } @@ -158,10 +169,10 @@ pub fn cargo_test(package: &PackageOpt, backend: Backends) -> anyhow::Result<()> } /// Use mdbook to build the book -pub fn cargo_book(cargoarg: &Option<&str>) -> anyhow::Result<()> { +pub fn cargo_book(arguments: &Option) -> anyhow::Result<()> { command_parser( &CargoCommand::Book { - mdbookarg: cargoarg, + arguments: arguments.clone(), }, false, )?; @@ -218,7 +229,7 @@ pub fn build_and_check_size( cargoarg: &Option<&str>, backend: Backends, examples: &[String], - size_arguments: &Option, + arguments: &Option, ) -> anyhow::Result<()> { examples.into_par_iter().for_each(|example| { // Make sure the requested example(s) are built @@ -247,7 +258,7 @@ pub fn build_and_check_size( backend.to_rtic_feature() )), mode: BuildMode::Release, - arguments: size_arguments.clone(), + arguments: arguments.clone(), }; if let Err(err) = command_parser(&cmd, false) { error!("{err}"); diff --git a/xtask/src/command.rs b/xtask/src/command.rs index b6602ee..6dd661e 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -1,4 +1,4 @@ -use crate::{debug, Package, RunResult, Sizearguments, TestRunError}; +use crate::{debug, ExtraArguments, Package, RunResult, TestRunError}; use core::fmt; use os_pipe::pipe; use std::{fs::File, io::Read, process::Command}; @@ -70,6 +70,7 @@ pub enum CargoCommand<'a> { Doc { cargoarg: &'a Option<&'a str>, features: Option, + arguments: Option, }, Test { package: Option, @@ -77,7 +78,7 @@ pub enum CargoCommand<'a> { test: Option, }, Book { - mdbookarg: &'a Option<&'a str>, + arguments: Option, }, ExampleSize { cargoarg: &'a Option<&'a str>, @@ -85,7 +86,7 @@ pub enum CargoCommand<'a> { target: &'a str, features: Option, mode: BuildMode, - arguments: Option, + arguments: Option, }, } @@ -238,7 +239,11 @@ impl<'a> CargoCommand<'a> { } args } - CargoCommand::Doc { cargoarg, features } => { + CargoCommand::Doc { + cargoarg, + features, + arguments, + } => { let mut args = vec!["+nightly"]; if let Some(cargoarg) = cargoarg { args.extend_from_slice(&[cargoarg]); @@ -249,6 +254,11 @@ impl<'a> CargoCommand<'a> { 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 { @@ -271,15 +281,17 @@ impl<'a> CargoCommand<'a> { } args } - CargoCommand::Book { mdbookarg } => { + CargoCommand::Book { arguments } => { let mut args = vec![]; - args.extend_from_slice(&[self.name()]); - - if let Some(arg) = mdbookarg { - args.extend_from_slice(&[arg]); + 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 + args.extend_from_slice(&[self.name()]); } - args.extend_from_slice(&["book/en"]); args } @@ -364,7 +376,7 @@ impl<'a> CargoCommand<'a> { if let Some(flag) = mode.to_flag() { args.push(flag); } - if let Some(Sizearguments::Other(arguments)) = arguments { + if let Some(ExtraArguments::Other(arguments)) = arguments { // Arguments to cargo size must be passed after "--" args.extend_from_slice(&["--"]); for arg in arguments { diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 6bf9317..aed74eb 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -4,7 +4,7 @@ mod cargo_commands; mod command; use anyhow::bail; -use argument_parsing::{Package, Sizearguments}; +use argument_parsing::{ExtraArguments, Package}; use clap::Parser; use core::fmt; use diffy::{create_patch, PatchFormatter}; @@ -230,12 +230,7 @@ fn main() -> anyhow::Result<()> { Commands::Size(args) => { // x86_64 target not valid info!("Measuring for backend: {backend:?}"); - build_and_check_size( - &cargologlevel, - backend, - &examples_to_run, - &args.sizearguments, - )?; + build_and_check_size(&cargologlevel, backend, &examples_to_run, &args.arguments)?; } Commands::Qemu(args) | Commands::Run(args) => { // x86_64 target not valid @@ -247,17 +242,17 @@ fn main() -> anyhow::Result<()> { args.overwrite_expected, )?; } - Commands::Doc => { + Commands::Doc(args) => { info!("Running cargo doc on backend: {backend:?}"); - cargo_doc(&cargologlevel, backend)?; + cargo_doc(&cargologlevel, backend, &args.arguments)?; } Commands::Test(args) => { info!("Running cargo test on backend: {backend:?}"); cargo_test(&args, backend)?; } - Commands::Book => { - info!("Running mdbook build"); - cargo_book(&cargologlevel)?; + Commands::Book(args) => { + info!("Running mdbook"); + cargo_book(&args.arguments)?; } } -- cgit v1.2.3 From 81ca9060438a43f02d1d6865834a3d4401d610d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Thu, 2 Mar 2023 22:02:54 +0100 Subject: xtask: Rename: name->command, command->executable --- xtask/src/command.rs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/command.rs b/xtask/src/command.rs index 6dd661e..42a5cac 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -91,7 +91,7 @@ pub enum CargoCommand<'a> { } impl<'a> CargoCommand<'a> { - fn name(&self) -> &str { + fn command(&self) -> &str { match self { CargoCommand::Run { .. } | CargoCommand::Qemu { .. } => "run", CargoCommand::ExampleCheck { .. } | CargoCommand::Check { .. } => "check", @@ -104,7 +104,7 @@ impl<'a> CargoCommand<'a> { CargoCommand::Test { .. } => "test", } } - pub fn command(&self) -> &str { + pub fn executable(&self) -> &str { match self { CargoCommand::Run { .. } | CargoCommand::Qemu { .. } @@ -135,7 +135,7 @@ impl<'a> CargoCommand<'a> { if let Some(cargoarg) = cargoarg { args.extend_from_slice(&[cargoarg]); } - args.extend_from_slice(&[self.name(), "--example", example, "--target", target]); + args.extend_from_slice(&[self.command(), "--example", example, "--target", target]); if let Some(feature) = features { args.extend_from_slice(&["--features", feature]); @@ -156,7 +156,7 @@ impl<'a> CargoCommand<'a> { if let Some(cargoarg) = cargoarg { args.extend_from_slice(&[cargoarg]); } - args.extend_from_slice(&[self.name(), "--example", example, "--target", target]); + args.extend_from_slice(&[self.command(), "--example", example, "--target", target]); if let Some(feature) = features { args.extend_from_slice(&["--features", feature]); @@ -178,7 +178,7 @@ impl<'a> CargoCommand<'a> { args.extend_from_slice(&[cargoarg]); } - args.extend_from_slice(&[self.name(), "--target", target]); + args.extend_from_slice(&[self.command(), "--target", target]); if let Some(package) = package { args.extend_from_slice(&["--package", package.name()]); @@ -203,7 +203,7 @@ impl<'a> CargoCommand<'a> { if let Some(cargoarg) = cargoarg { args.extend_from_slice(&[cargoarg]); } - args.extend_from_slice(&[self.name()]); + args.extend_from_slice(&[self.command()]); if let Some(package) = package { args.extend_from_slice(&["--package", package.name()]); @@ -228,7 +228,7 @@ impl<'a> CargoCommand<'a> { args.extend_from_slice(&[cargoarg]); } - args.extend_from_slice(&[self.name()]); + args.extend_from_slice(&[self.command()]); if let Some(package) = package { args.extend_from_slice(&["--package", package.name()]); @@ -249,7 +249,7 @@ impl<'a> CargoCommand<'a> { args.extend_from_slice(&[cargoarg]); } - args.extend_from_slice(&[self.name()]); + args.extend_from_slice(&[self.command()]); if let Some(feature) = features { args.extend_from_slice(&["--features", feature]); @@ -267,7 +267,7 @@ impl<'a> CargoCommand<'a> { test, } => { let mut args = vec!["+nightly"]; - args.extend_from_slice(&[self.name()]); + args.extend_from_slice(&[self.command()]); if let Some(package) = package { args.extend_from_slice(&["--package", package.name()]); @@ -290,7 +290,7 @@ impl<'a> CargoCommand<'a> { } } else { // If no argument given, run mdbook build - args.extend_from_slice(&[self.name()]); + args.extend_from_slice(&[self.command()]); } args.extend_from_slice(&["book/en"]); args @@ -300,7 +300,7 @@ impl<'a> CargoCommand<'a> { package, check_only, } => { - let mut args = vec!["+nightly", self.name()]; + let mut args = vec!["+nightly", self.command()]; if let Some(cargoarg) = cargoarg { args.extend_from_slice(&[cargoarg]); } @@ -325,7 +325,7 @@ impl<'a> CargoCommand<'a> { if let Some(cargoarg) = cargoarg { args.extend_from_slice(&[cargoarg]); } - args.extend_from_slice(&[self.name(), "--example", example, "--target", target]); + args.extend_from_slice(&[self.command(), "--example", example, "--target", target]); if let Some(feature) = features { args.extend_from_slice(&["--features", feature]); @@ -346,7 +346,7 @@ impl<'a> CargoCommand<'a> { if let Some(cargoarg) = cargoarg { args.extend_from_slice(&[cargoarg]); } - args.extend_from_slice(&[self.name(), "--example", example, "--target", target]); + args.extend_from_slice(&[self.command(), "--example", example, "--target", target]); if let Some(feature) = features { args.extend_from_slice(&["--features", feature]); @@ -368,7 +368,7 @@ impl<'a> CargoCommand<'a> { if let Some(cargoarg) = cargoarg { args.extend_from_slice(&[cargoarg]); } - args.extend_from_slice(&[self.name(), "--example", example, "--target", target]); + args.extend_from_slice(&[self.command(), "--example", example, "--target", target]); if let Some(feature_name) = features { args.extend_from_slice(&["--features", feature_name]); @@ -413,9 +413,9 @@ impl fmt::Display for BuildMode { pub fn run_command(command: &CargoCommand) -> anyhow::Result { let (mut reader, writer) = pipe()?; let (mut error_reader, error_writer) = pipe()?; - debug!("👟 {} {}", command.command(), command.args().join(" ")); + 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) -- cgit v1.2.3 From 0723310ff7584caf6b86b3500f94925d921cf02c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Sat, 4 Mar 2023 00:08:11 +0100 Subject: xtask: Book: Allow fully custom arguments --- xtask/src/command.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'xtask/src') diff --git a/xtask/src/command.rs b/xtask/src/command.rs index 42a5cac..6e91a52 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -290,9 +290,10 @@ impl<'a> CargoCommand<'a> { } } 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.extend_from_slice(&["book/en"]); args } CargoCommand::Format { -- cgit v1.2.3 From 2e63f5bca30acdec81495e0dc59aa6f7ebff5976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Sat, 4 Mar 2023 02:11:50 +0100 Subject: ci: Add rtic-uitest feature Fixes the trybuild ui tests for rtic crate --- xtask/src/argument_parsing.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'xtask/src') diff --git a/xtask/src/argument_parsing.rs b/xtask/src/argument_parsing.rs index 1fc06c1..aef5e3a 100644 --- a/xtask/src/argument_parsing.rs +++ b/xtask/src/argument_parsing.rs @@ -38,9 +38,10 @@ impl TestMetadata { match package { Package::Rtic => { let features = Some(format!( - "{},{}", + "{},{},{}", DEFAULT_FEATURES, backend.to_rtic_feature(), + "rtic-uitest" )); CargoCommand::Test { package: Some(package), -- cgit v1.2.3 From 3789798e33f613dbdc91576eb57bf7691ba0568a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Sat, 4 Mar 2023 20:52:29 +0100 Subject: xtask: clippy fixes --- xtask/src/argument_parsing.rs | 3 +++ xtask/src/cargo_commands.rs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'xtask/src') diff --git a/xtask/src/argument_parsing.rs b/xtask/src/argument_parsing.rs index aef5e3a..3e5afc3 100644 --- a/xtask/src/argument_parsing.rs +++ b/xtask/src/argument_parsing.rs @@ -88,6 +88,7 @@ pub enum Backends { } impl Backends { + #[allow(clippy::wrong_self_convention)] pub fn to_target(&self) -> &str { match self { Backends::Thumbv6 => ARMV6M, @@ -97,6 +98,7 @@ impl Backends { } } + #[allow(clippy::wrong_self_convention)] pub fn to_rtic_feature(&self) -> &str { match self { Backends::Thumbv6 => "thumbv6-backend", @@ -105,6 +107,7 @@ impl Backends { Backends::Thumbv8Main => "thumbv8main-backend", } } + #[allow(clippy::wrong_self_convention)] pub fn to_rtic_macros_feature(&self) -> &str { match self { Backends::Thumbv6 => "cortex-m-source-masking", diff --git a/xtask/src/cargo_commands.rs b/xtask/src/cargo_commands.rs index f262c9f..7ac7aea 100644 --- a/xtask/src/cargo_commands.rs +++ b/xtask/src/cargo_commands.rs @@ -154,7 +154,7 @@ pub fn cargo_test(package: &PackageOpt, backend: Backends) -> anyhow::Result<()> ] { let mut error_messages = vec![]; let cmd = &TestMetadata::match_package(package, backend); - if let Err(err) = command_parser(&cmd, false) { + if let Err(err) = command_parser(cmd, false) { error_messages.push(err); } -- cgit v1.2.3 From 62e687242ad1e92f9172f6cc897407156cf42e7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Sat, 4 Mar 2023 21:03:46 +0100 Subject: ci: Add v6 uitest feature --- xtask/src/argument_parsing.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'xtask/src') diff --git a/xtask/src/argument_parsing.rs b/xtask/src/argument_parsing.rs index 3e5afc3..70bae73 100644 --- a/xtask/src/argument_parsing.rs +++ b/xtask/src/argument_parsing.rs @@ -41,7 +41,7 @@ impl TestMetadata { "{},{},{}", DEFAULT_FEATURES, backend.to_rtic_feature(), - "rtic-uitest" + backend.to_rtic_uitest_feature(), )); CargoCommand::Test { package: Some(package), @@ -110,10 +110,15 @@ impl Backends { #[allow(clippy::wrong_self_convention)] pub 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", + Backends::Thumbv6 | Backends::Thumbv8Base => "cortex-m-source-masking", + Backends::Thumbv7 | Backends::Thumbv8Main => "cortex-m-basepri", + } + } + #[allow(clippy::wrong_self_convention)] + pub fn to_rtic_uitest_feature(&self) -> &str { + match self { + Backends::Thumbv6 | Backends::Thumbv8Base => "rtic-uitestv6", + Backends::Thumbv7 | Backends::Thumbv8Main => "rtic-uitestv7", } } } -- cgit v1.2.3 From a5ede5408cff4834608134dd6a07e4978d9bbd08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Sat, 4 Mar 2023 21:32:37 +0100 Subject: xtask: rtic-monotonics: no tests argument --- xtask/src/argument_parsing.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'xtask/src') diff --git a/xtask/src/argument_parsing.rs b/xtask/src/argument_parsing.rs index 70bae73..8795213 100644 --- a/xtask/src/argument_parsing.rs +++ b/xtask/src/argument_parsing.rs @@ -67,7 +67,7 @@ impl TestMetadata { Package::RticMonotonics => CargoCommand::Test { package: Some(package), features: None, - test: Some("tests".to_owned()), + test: None, }, Package::RticTime => CargoCommand::Test { package: Some(package), -- cgit v1.2.3