More emojis and correct place for things

This commit is contained in:
datdenkikniet 2023-04-15 13:45:58 +02:00
parent df69b35c25
commit 461023e3b8
4 changed files with 147 additions and 160 deletions

View file

@ -113,7 +113,7 @@ pub enum Backends {
impl Backends { impl Backends {
#[allow(clippy::wrong_self_convention)] #[allow(clippy::wrong_self_convention)]
pub fn to_target(&self) -> Target { pub fn to_target(&self) -> Target<'static> {
match self { match self {
Backends::Thumbv6 => ARMV6M, Backends::Thumbv6 => ARMV6M,
Backends::Thumbv7 => ARMV7M, Backends::Thumbv7 => ARMV7M,
@ -123,7 +123,7 @@ impl Backends {
} }
#[allow(clippy::wrong_self_convention)] #[allow(clippy::wrong_self_convention)]
pub fn to_rtic_feature(&self) -> &str { pub fn to_rtic_feature(&self) -> &'static str {
match self { match self {
Backends::Thumbv6 => "thumbv6-backend", Backends::Thumbv6 => "thumbv6-backend",
Backends::Thumbv7 => "thumbv7-backend", Backends::Thumbv7 => "thumbv7-backend",
@ -132,14 +132,14 @@ impl Backends {
} }
} }
#[allow(clippy::wrong_self_convention)] #[allow(clippy::wrong_self_convention)]
pub fn to_rtic_macros_feature(&self) -> &str { pub fn to_rtic_macros_feature(&self) -> &'static str {
match self { match self {
Backends::Thumbv6 | Backends::Thumbv8Base => "cortex-m-source-masking", Backends::Thumbv6 | Backends::Thumbv8Base => "cortex-m-source-masking",
Backends::Thumbv7 | Backends::Thumbv8Main => "cortex-m-basepri", Backends::Thumbv7 | Backends::Thumbv8Main => "cortex-m-basepri",
} }
} }
#[allow(clippy::wrong_self_convention)] #[allow(clippy::wrong_self_convention)]
pub fn to_rtic_uitest_feature(&self) -> &str { pub fn to_rtic_uitest_feature(&self) -> &'static str {
match self { match self {
Backends::Thumbv6 | Backends::Thumbv8Base => "rtic-uitestv6", Backends::Thumbv6 | Backends::Thumbv8Base => "rtic-uitestv6",
Backends::Thumbv7 | Backends::Thumbv8Main => "rtic-uitestv7", Backends::Thumbv7 | Backends::Thumbv8Main => "rtic-uitestv7",
@ -205,9 +205,6 @@ pub struct Cli {
#[derive(Debug, Clone, Subcommand)] #[derive(Debug, Clone, Subcommand)]
pub enum Commands { pub enum Commands {
/// Check formatting
FormatCheck(PackageOpt),
/// Format code /// Format code
#[clap(alias = "fmt")] #[clap(alias = "fmt")]
Format(FormatOpt), Format(FormatOpt),
@ -270,9 +267,9 @@ pub enum Commands {
pub struct FormatOpt { pub struct FormatOpt {
#[clap(flatten)] #[clap(flatten)]
pub package: PackageOpt, pub package: PackageOpt,
/// Only check formatting, without applying fixes. /// Apply formatting fixes immediately.
#[clap(short, long, alias = "check-only")] #[clap(short, long)]
pub check: bool, pub apply: bool,
} }
#[derive(Args, Debug, Clone)] #[derive(Args, Debug, Clone)]

View file

@ -3,14 +3,14 @@ use crate::{
command::{BuildMode, CargoCommand}, command::{BuildMode, CargoCommand},
command_parser, RunResult, command_parser, RunResult,
}; };
use log::{error, info, Level}; use log::error;
#[cfg(feature = "rayon")] #[cfg(feature = "rayon")]
use rayon::prelude::*; use rayon::prelude::*;
use iters::*; use iters::*;
enum FinalRunResult<'c> { pub enum FinalRunResult<'c> {
Success(CargoCommand<'c>, RunResult), Success(CargoCommand<'c>, RunResult),
Failed(CargoCommand<'c>, RunResult), Failed(CargoCommand<'c>, RunResult),
CommandError(anyhow::Error), CommandError(anyhow::Error),
@ -36,71 +36,10 @@ fn run_and_convert<'a>(
} }
} }
fn handle_results(results: Vec<FinalRunResult>) -> anyhow::Result<()> { pub trait CoalescingRunner<'c> {
let errors = results.iter().filter_map(|r| {
if let FinalRunResult::Failed(c, r) = r {
Some((c, r))
} else {
None
}
});
let successes = results.iter().filter_map(|r| {
if let FinalRunResult::Success(c, r) = r {
Some((c, r))
} else {
None
}
});
let log_stdout_stderr = |level: Level| {
move |(command, result): (&CargoCommand, &RunResult)| {
let stdout = &result.stdout;
let stderr = &result.stderr;
if !stdout.is_empty() && !stderr.is_empty() {
log::log!(
level,
"Output for \"{command}\"\nStdout:\n{stdout}\nStderr:\n{stderr}"
);
} else if !stdout.is_empty() {
log::log!(
level,
"Output for \"{command}\":\nStdout:\n{}",
stdout.trim_end()
);
} else if !stderr.is_empty() {
log::log!(
level,
"Output for \"{command}\"\nStderr:\n{}",
stderr.trim_end()
);
}
}
};
successes.clone().for_each(log_stdout_stderr(Level::Debug));
errors.clone().for_each(log_stdout_stderr(Level::Error));
successes.for_each(|(cmd, _)| {
info!("Success: {cmd}");
});
errors.clone().for_each(|(cmd, _)| {
error!("Failed: {cmd}");
});
let ecount = errors.count();
if ecount != 0 {
Err(anyhow::anyhow!("{ecount} commands failed."))
} else {
Ok(())
}
}
pub trait CoalescingRunning {
/// Run all the commands in this iterator, and coalesce the results into /// Run all the commands in this iterator, and coalesce the results into
/// one error (if any individual commands failed) /// one error (if any individual commands failed)
fn run_and_coalesce(self) -> anyhow::Result<()>; fn run_and_coalesce(self) -> Vec<FinalRunResult<'c>>;
} }
#[cfg(not(feature = "rayon"))] #[cfg(not(feature = "rayon"))]
@ -111,13 +50,12 @@ mod iters {
examples.into_iter() examples.into_iter()
} }
impl<'g, 'c, I> CoalescingRunning for I impl<'g, 'c, I> CoalescingRunner<'c> for I
where where
I: Iterator<Item = (&'g Globals, CargoCommand<'c>, bool)>, I: Iterator<Item = (&'g Globals, CargoCommand<'c>, bool)>,
{ {
fn run_and_coalesce(self) -> anyhow::Result<()> { fn run_and_coalesce(self) -> Vec<FinalRunResult<'c>> {
let results: Vec<_> = self.map(run_and_convert).collect(); self.map(run_and_convert).collect()
handle_results(results)
} }
} }
} }
@ -130,28 +68,26 @@ mod iters {
examples.into_par_iter() examples.into_par_iter()
} }
impl<'g, 'c, I> CoalescingRunning for I impl<'g, 'c, I> CoalescingRunner<'c> for I
where where
I: ParallelIterator<Item = (&'g Globals, CargoCommand<'c>, bool)>, I: ParallelIterator<Item = (&'g Globals, CargoCommand<'c>, bool)>,
{ {
fn run_and_coalesce(self) -> anyhow::Result<()> { fn run_and_coalesce(self) -> Vec<FinalRunResult<'c>> {
let results: Vec<_> = self.map(run_and_convert).collect(); self.map(run_and_convert).collect()
handle_results(results)
} }
} }
} }
/// Cargo command to either build or check /// Cargo command to either build or check
pub fn cargo( pub fn cargo<'c>(
globals: &Globals, globals: &Globals,
operation: BuildOrCheck, operation: BuildOrCheck,
cargoarg: &Option<&str>, cargoarg: &'c Option<&'c str>,
package: &PackageOpt, package: &'c PackageOpt,
backend: Backends, backend: Backends,
) -> anyhow::Result<()> { ) -> Vec<FinalRunResult<'c>> {
let runner = package.packages().map(|package| { let runner = package.packages().map(move |package| {
let target = backend.to_target(); let target = backend.to_target();
let features = package.extract_features(target, backend); let features = package.extract_features(target, backend);
let command = match operation { let command = match operation {
@ -180,13 +116,13 @@ pub fn cargo(
/// Cargo command to either build or check all examples /// Cargo command to either build or check all examples
/// ///
/// The examples are in rtic/examples /// The examples are in rtic/examples
pub fn cargo_example( pub fn cargo_example<'c>(
globals: &Globals, globals: &Globals,
operation: BuildOrCheck, operation: BuildOrCheck,
cargoarg: &Option<&str>, cargoarg: &'c Option<&'c str>,
backend: Backends, backend: Backends,
examples: &[String], examples: &'c [String],
) -> anyhow::Result<()> { ) -> Vec<FinalRunResult<'c>> {
let runner = examples_iter(examples).map(|example| { let runner = examples_iter(examples).map(|example| {
let features = Some(backend.to_target().and_features(backend.to_rtic_feature())); let features = Some(backend.to_target().and_features(backend.to_rtic_feature()));
@ -212,12 +148,12 @@ pub fn cargo_example(
} }
/// Run cargo clippy on selected package /// Run cargo clippy on selected package
pub fn cargo_clippy( pub fn cargo_clippy<'c>(
globals: &Globals, globals: &Globals,
cargoarg: &Option<&str>, cargoarg: &'c Option<&'c str>,
package: &PackageOpt, package: &'c PackageOpt,
backend: Backends, backend: Backends,
) -> anyhow::Result<()> { ) -> Vec<FinalRunResult<'c>> {
let runner = package.packages().map(|p| { let runner = package.packages().map(|p| {
let target = backend.to_target(); let target = backend.to_target();
let features = p.extract_features(target, backend); let features = p.extract_features(target, backend);
@ -238,12 +174,12 @@ pub fn cargo_clippy(
} }
/// Run cargo fmt on selected package /// Run cargo fmt on selected package
pub fn cargo_format( pub fn cargo_format<'c>(
globals: &Globals, globals: &Globals,
cargoarg: &Option<&str>, cargoarg: &'c Option<&'c str>,
package: &PackageOpt, package: &'c PackageOpt,
check_only: bool, check_only: bool,
) -> anyhow::Result<()> { ) -> Vec<FinalRunResult<'c>> {
let runner = package.packages().map(|p| { let runner = package.packages().map(|p| {
( (
globals, globals,
@ -259,34 +195,31 @@ pub fn cargo_format(
} }
/// Run cargo doc /// Run cargo doc
pub fn cargo_doc( pub fn cargo_doc<'c>(
globals: &Globals, globals: &Globals,
cargoarg: &Option<&str>, cargoarg: &'c Option<&'c str>,
backend: Backends, backend: Backends,
arguments: &Option<ExtraArguments>, arguments: &'c Option<ExtraArguments>,
) -> anyhow::Result<()> { ) -> Vec<FinalRunResult<'c>> {
let features = Some(backend.to_target().and_features(backend.to_rtic_feature())); let features = Some(backend.to_target().and_features(backend.to_rtic_feature()));
command_parser( let command = CargoCommand::Doc {
globals, cargoarg,
&CargoCommand::Doc { features,
cargoarg, arguments: arguments.clone(),
features, };
arguments: arguments.clone(),
}, vec![run_and_convert((globals, command, false))]
false,
)?;
Ok(())
} }
/// Run cargo test on the selected package or all packages /// Run cargo test on the selected package or all packages
/// ///
/// If no package is specified, loop through all packages /// If no package is specified, loop through all packages
pub fn cargo_test( pub fn cargo_test<'c>(
globals: &Globals, globals: &Globals,
package: &PackageOpt, package: &'c PackageOpt,
backend: Backends, backend: Backends,
) -> anyhow::Result<()> { ) -> Vec<FinalRunResult<'c>> {
package package
.packages() .packages()
.map(|p| (globals, TestMetadata::match_package(p, backend), false)) .map(|p| (globals, TestMetadata::match_package(p, backend), false))
@ -294,29 +227,29 @@ pub fn cargo_test(
} }
/// Use mdbook to build the book /// Use mdbook to build the book
pub fn cargo_book( pub fn cargo_book<'c>(
globals: &Globals, globals: &Globals,
arguments: &Option<ExtraArguments>, arguments: &'c Option<ExtraArguments>,
) -> anyhow::Result<RunResult> { ) -> Vec<FinalRunResult<'c>> {
command_parser( vec![run_and_convert((
globals, globals,
&CargoCommand::Book { CargoCommand::Book {
arguments: arguments.clone(), arguments: arguments.clone(),
}, },
false, false,
) ))]
} }
/// Run examples /// Run examples
/// ///
/// Supports updating the expected output via the overwrite argument /// Supports updating the expected output via the overwrite argument
pub fn run_test( pub fn run_test<'c>(
globals: &Globals, globals: &Globals,
cargoarg: &Option<&str>, cargoarg: &'c Option<&'c str>,
backend: Backends, backend: Backends,
examples: &[String], examples: &'c [String],
overwrite: bool, overwrite: bool,
) -> anyhow::Result<()> { ) -> Vec<FinalRunResult<'c>> {
let target = backend.to_target(); let target = backend.to_target();
let features = Some(target.and_features(backend.to_rtic_feature())); let features = Some(target.and_features(backend.to_rtic_feature()));
@ -348,13 +281,13 @@ pub fn run_test(
} }
/// Check the binary sizes of examples /// Check the binary sizes of examples
pub fn build_and_check_size( pub fn build_and_check_size<'c>(
globals: &Globals, globals: &Globals,
cargoarg: &Option<&str>, cargoarg: &'c Option<&'c str>,
backend: Backends, backend: Backends,
examples: &[String], examples: &'c [String],
arguments: &Option<ExtraArguments>, arguments: &'c Option<ExtraArguments>,
) -> anyhow::Result<()> { ) -> Vec<FinalRunResult<'c>> {
let target = backend.to_target(); let target = backend.to_target();
let features = Some(target.and_features(backend.to_rtic_feature())); let features = Some(target.and_features(backend.to_rtic_feature()));

View file

@ -1,4 +1,8 @@
use crate::{debug, ExtraArguments, Package, RunResult, Target, TestRunError}; use log::{error, info, Level};
use crate::{
cargo_commands::FinalRunResult, ExtraArguments, Package, RunResult, Target, TestRunError,
};
use core::fmt; use core::fmt;
use std::{ use std::{
fs::File, fs::File,
@ -279,7 +283,7 @@ impl core::fmt::Display for CargoCommand<'_> {
.map(|t| format!("test {t}")) .map(|t| format!("test {t}"))
.unwrap_or("all tests".into()); .unwrap_or("all tests".into());
let feat = feat(features); let feat = feat(features);
write!(f, "Run {test} in {p} ({feat})") write!(f, "Run {test} in {p} (features: {feat})")
} }
CargoCommand::Book { arguments: _ } => write!(f, "Build the book"), CargoCommand::Book { arguments: _ } => write!(f, "Build the book"),
CargoCommand::ExampleSize { CargoCommand::ExampleSize {
@ -652,7 +656,7 @@ impl fmt::Display for BuildMode {
} }
pub fn run_command(command: &CargoCommand, stderr_mode: OutputMode) -> anyhow::Result<RunResult> { pub fn run_command(command: &CargoCommand, stderr_mode: OutputMode) -> anyhow::Result<RunResult> {
debug!("👟 {command}"); log::info!("👟 {command}");
let result = Command::new(command.executable()) let result = Command::new(command.executable())
.args(command.args()) .args(command.args())
@ -697,3 +701,64 @@ pub fn run_successful(run: &RunResult, expected_output_file: &str) -> Result<(),
Ok(()) Ok(())
} }
} }
pub fn handle_results(results: Vec<FinalRunResult>) -> anyhow::Result<()> {
let errors = results.iter().filter_map(|r| {
if let FinalRunResult::Failed(c, r) = r {
Some((c, r))
} else {
None
}
});
let successes = results.iter().filter_map(|r| {
if let FinalRunResult::Success(c, r) = r {
Some((c, r))
} else {
None
}
});
let log_stdout_stderr = |level: Level| {
move |(command, result): (&CargoCommand, &RunResult)| {
let stdout = &result.stdout;
let stderr = &result.stderr;
if !stdout.is_empty() && !stderr.is_empty() {
log::log!(
level,
"Output for \"{command}\"\nStdout:\n{stdout}\nStderr:\n{stderr}"
);
} else if !stdout.is_empty() {
log::log!(
level,
"Output for \"{command}\":\nStdout:\n{}",
stdout.trim_end()
);
} else if !stderr.is_empty() {
log::log!(
level,
"Output for \"{command}\"\nStderr:\n{}",
stderr.trim_end()
);
}
}
};
successes.clone().for_each(log_stdout_stderr(Level::Debug));
errors.clone().for_each(log_stdout_stderr(Level::Error));
successes.for_each(|(cmd, _)| {
info!("✅ Success: {cmd}");
});
errors.clone().for_each(|(cmd, _)| {
error!("❌ Failed: {cmd}");
});
let ecount = errors.count();
if ecount != 0 {
Err(anyhow::anyhow!("{ecount} commands failed."))
} else {
Ok(())
}
}

View file

@ -18,7 +18,7 @@ use std::{
str, str,
}; };
use log::{debug, error, info, log_enabled, trace, Level}; use log::{error, info, log_enabled, trace, Level};
use crate::{ use crate::{
argument_parsing::{Backends, BuildOrCheck, Cli, Commands}, argument_parsing::{Backends, BuildOrCheck, Cli, Commands},
@ -27,7 +27,7 @@ use crate::{
build_and_check_size, cargo, cargo_book, cargo_clippy, cargo_doc, cargo_example, build_and_check_size, cargo, cargo_book, cargo_clippy, cargo_doc, cargo_example,
cargo_format, cargo_test, run_test, cargo_format, cargo_test, run_test,
}, },
command::{run_command, run_successful, CargoCommand}, command::{handle_results, run_command, run_successful, CargoCommand},
}; };
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@ -217,27 +217,19 @@ fn main() -> anyhow::Result<()> {
Some("--quiet") Some("--quiet")
}; };
match cli.command { let final_run_results = match &cli.command {
Commands::FormatCheck(args) => { Commands::Format(args) => cargo_format(globals, &cargologlevel, &args.package, !args.apply),
info!("Running cargo fmt --check: {args:?}");
let check_only = true;
cargo_format(globals, &cargologlevel, &args, check_only)?;
}
Commands::Format(args) => {
info!("Running cargo fmt: {args:?}");
cargo_format(globals, &cargologlevel, &args.package, args.check)?;
}
Commands::Clippy(args) => { Commands::Clippy(args) => {
info!("Running clippy on backend: {backend:?}"); info!("Running clippy on backend: {backend:?}");
cargo_clippy(globals, &cargologlevel, &args, backend)?; cargo_clippy(globals, &cargologlevel, &args, backend)
} }
Commands::Check(args) => { Commands::Check(args) => {
info!("Checking on backend: {backend:?}"); info!("Checking on backend: {backend:?}");
cargo(globals, BuildOrCheck::Check, &cargologlevel, &args, backend)?; cargo(globals, BuildOrCheck::Check, &cargologlevel, &args, backend)
} }
Commands::Build(args) => { Commands::Build(args) => {
info!("Building for backend: {backend:?}"); info!("Building for backend: {backend:?}");
cargo(globals, BuildOrCheck::Build, &cargologlevel, &args, backend)?; cargo(globals, BuildOrCheck::Build, &cargologlevel, &args, backend)
} }
Commands::ExampleCheck => { Commands::ExampleCheck => {
info!("Checking on backend: {backend:?}"); info!("Checking on backend: {backend:?}");
@ -247,7 +239,7 @@ fn main() -> anyhow::Result<()> {
&cargologlevel, &cargologlevel,
backend, backend,
&examples_to_run, &examples_to_run,
)?; )
} }
Commands::ExampleBuild => { Commands::ExampleBuild => {
info!("Building for backend: {backend:?}"); info!("Building for backend: {backend:?}");
@ -257,7 +249,7 @@ fn main() -> anyhow::Result<()> {
&cargologlevel, &cargologlevel,
backend, backend,
&examples_to_run, &examples_to_run,
)?; )
} }
Commands::Size(args) => { Commands::Size(args) => {
// x86_64 target not valid // x86_64 target not valid
@ -268,7 +260,7 @@ fn main() -> anyhow::Result<()> {
backend, backend,
&examples_to_run, &examples_to_run,
&args.arguments, &args.arguments,
)?; )
} }
Commands::Qemu(args) | Commands::Run(args) => { Commands::Qemu(args) | Commands::Run(args) => {
// x86_64 target not valid // x86_64 target not valid
@ -279,23 +271,23 @@ fn main() -> anyhow::Result<()> {
backend, backend,
&examples_to_run, &examples_to_run,
args.overwrite_expected, args.overwrite_expected,
)?; )
} }
Commands::Doc(args) => { Commands::Doc(args) => {
info!("Running cargo doc on backend: {backend:?}"); info!("Running cargo doc on backend: {backend:?}");
cargo_doc(globals, &cargologlevel, backend, &args.arguments)?; cargo_doc(globals, &cargologlevel, backend, &args.arguments)
} }
Commands::Test(args) => { Commands::Test(args) => {
info!("Running cargo test on backend: {backend:?}"); info!("Running cargo test on backend: {backend:?}");
cargo_test(globals, &args, backend)?; cargo_test(globals, &args, backend)
} }
Commands::Book(args) => { Commands::Book(args) => {
info!("Running mdbook"); info!("Running mdbook");
cargo_book(globals, &args.arguments)?; cargo_book(globals, &args.arguments)
} }
} };
Ok(()) handle_results(final_run_results)
} }
// run example binary `example` // run example binary `example`