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

View file

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

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 std::{
fs::File,
@ -279,7 +283,7 @@ impl core::fmt::Display for CargoCommand<'_> {
.map(|t| format!("test {t}"))
.unwrap_or("all tests".into());
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::ExampleSize {
@ -652,7 +656,7 @@ impl fmt::Display for BuildMode {
}
pub fn run_command(command: &CargoCommand, stderr_mode: OutputMode) -> anyhow::Result<RunResult> {
debug!("👟 {command}");
log::info!("👟 {command}");
let result = Command::new(command.executable())
.args(command.args())
@ -697,3 +701,64 @@ pub fn run_successful(run: &RunResult, expected_output_file: &str) -> Result<(),
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,
};
use log::{debug, error, info, log_enabled, trace, Level};
use log::{error, info, log_enabled, trace, Level};
use crate::{
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,
cargo_format, cargo_test, run_test,
},
command::{run_command, run_successful, CargoCommand},
command::{handle_results, run_command, run_successful, CargoCommand},
};
#[derive(Debug, Clone, Copy)]
@ -217,27 +217,19 @@ fn main() -> anyhow::Result<()> {
Some("--quiet")
};
match cli.command {
Commands::FormatCheck(args) => {
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)?;
}
let final_run_results = match &cli.command {
Commands::Format(args) => cargo_format(globals, &cargologlevel, &args.package, !args.apply),
Commands::Clippy(args) => {
info!("Running clippy on backend: {backend:?}");
cargo_clippy(globals, &cargologlevel, &args, backend)?;
cargo_clippy(globals, &cargologlevel, &args, backend)
}
Commands::Check(args) => {
info!("Checking on backend: {backend:?}");
cargo(globals, BuildOrCheck::Check, &cargologlevel, &args, backend)?;
cargo(globals, BuildOrCheck::Check, &cargologlevel, &args, backend)
}
Commands::Build(args) => {
info!("Building for backend: {backend:?}");
cargo(globals, BuildOrCheck::Build, &cargologlevel, &args, backend)?;
cargo(globals, BuildOrCheck::Build, &cargologlevel, &args, backend)
}
Commands::ExampleCheck => {
info!("Checking on backend: {backend:?}");
@ -247,7 +239,7 @@ fn main() -> anyhow::Result<()> {
&cargologlevel,
backend,
&examples_to_run,
)?;
)
}
Commands::ExampleBuild => {
info!("Building for backend: {backend:?}");
@ -257,7 +249,7 @@ fn main() -> anyhow::Result<()> {
&cargologlevel,
backend,
&examples_to_run,
)?;
)
}
Commands::Size(args) => {
// x86_64 target not valid
@ -268,7 +260,7 @@ fn main() -> anyhow::Result<()> {
backend,
&examples_to_run,
&args.arguments,
)?;
)
}
Commands::Qemu(args) | Commands::Run(args) => {
// x86_64 target not valid
@ -279,23 +271,23 @@ fn main() -> anyhow::Result<()> {
backend,
&examples_to_run,
args.overwrite_expected,
)?;
)
}
Commands::Doc(args) => {
info!("Running cargo doc on backend: {backend:?}");
cargo_doc(globals, &cargologlevel, backend, &args.arguments)?;
cargo_doc(globals, &cargologlevel, backend, &args.arguments)
}
Commands::Test(args) => {
info!("Running cargo test on backend: {backend:?}");
cargo_test(globals, &args, backend)?;
cargo_test(globals, &args, backend)
}
Commands::Book(args) => {
info!("Running mdbook");
cargo_book(globals, &args.arguments)?;
}
cargo_book(globals, &args.arguments)
}
};
Ok(())
handle_results(final_run_results)
}
// run example binary `example`