diff --git a/src/main.rs b/src/main.rs index ef4cff19..7b48405c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -38,7 +38,6 @@ mod ctrlc; mod error; mod execution_context; mod executor; -mod report; mod runner; #[cfg(windows)] mod self_renamer; @@ -200,26 +199,32 @@ fn run() -> Result<()> { step.run(&mut runner, &ctx)? } - if !runner.report().data().is_empty() { + let mut failed = false; + + let report = runner.report(); + if !report.is_empty() { print_separator(t!("Summary")); - for (key, result) in runner.report().data() { - print_result(key, result); - } - - #[cfg(target_os = "linux")] - { - if let Ok(distribution) = &distribution { - distribution.show_summary(); + for (key, result) in report { + if !failed && result.failed() { + failed = true; } + print_result(key, result); + } + } + + #[cfg(target_os = "linux")] + { + if let Ok(distribution) = &distribution { + distribution.show_summary(); } } - let mut post_command_failed = false; if let Some(commands) = config.post_commands() { for (name, command) in commands { - if generic::run_custom_command(name, command, &ctx).is_err() { - post_command_failed = true; + let result = generic::run_custom_command(name, command, &ctx); + if !failed && result.is_err() { + failed = true; } } } @@ -244,8 +249,6 @@ fn run() -> Result<()> { } } - let failed = post_command_failed || runner.report().data().iter().any(|(_, result)| result.failed()); - if !config.skip_notify() { notify_desktop( if failed { diff --git a/src/report.rs b/src/report.rs deleted file mode 100644 index 77e0d57a..00000000 --- a/src/report.rs +++ /dev/null @@ -1,45 +0,0 @@ -use std::borrow::Cow; - -pub enum StepResult { - Success, - Failure, - Ignored, - Skipped(String), -} - -impl StepResult { - pub fn failed(&self) -> bool { - match self { - StepResult::Success | StepResult::Ignored | StepResult::Skipped(_) => false, - StepResult::Failure => true, - } - } -} - -type CowString<'a> = Cow<'a, str>; -type ReportData<'a> = Vec<(CowString<'a>, StepResult)>; -pub struct Report<'a> { - data: ReportData<'a>, -} - -impl<'a> Report<'a> { - pub fn new() -> Self { - Self { data: Vec::new() } - } - - pub fn push_result(&mut self, result: Option<(M, StepResult)>) - where - M: Into>, - { - if let Some((key, success)) = result { - let key = key.into(); - - debug_assert!(!self.data.iter().any(|(k, _)| k == &key), "{key} already reported"); - self.data.push((key, success)); - } - } - - pub fn data(&self) -> &ReportData<'a> { - &self.data - } -} diff --git a/src/runner.rs b/src/runner.rs index 998aaece..53ea64a8 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -1,15 +1,34 @@ -use crate::ctrlc; -use crate::error::{DryRun, SkipStep}; -use crate::execution_context::ExecutionContext; -use crate::report::{Report, StepResult}; -use crate::step::Step; -use crate::terminal::print_error; -use crate::terminal::should_retry; use color_eyre::eyre::Result; use std::borrow::Cow; use std::fmt::Debug; use tracing::debug; +use crate::ctrlc; +use crate::error::{DryRun, SkipStep}; +use crate::execution_context::ExecutionContext; +use crate::step::Step; +use crate::terminal::{print_error, should_retry}; + +pub enum StepResult { + Success, + Failure, + Ignored, + Skipped(String), +} + +impl StepResult { + pub fn failed(&self) -> bool { + use StepResult::*; + + match self { + Success | Ignored | Skipped(_) => false, + Failure => true, + } + } +} + +type Report<'a> = Vec<(Cow<'a, str>, StepResult)>; + pub struct Runner<'a> { ctx: &'a ExecutionContext<'a>, report: Report<'a>, @@ -19,20 +38,25 @@ impl<'a> Runner<'a> { pub fn new(ctx: &'a ExecutionContext) -> Runner<'a> { Runner { ctx, - report: Report::new(), + report: Vec::new(), } } - pub fn execute(&mut self, step: Step, key: M, func: F) -> Result<()> + fn push_result(&mut self, key: Cow<'a, str>, result: StepResult) { + debug_assert!(!self.report.iter().any(|(k, _)| k == &key), "{key} already reported"); + self.report.push((key, result)); + } + + pub fn execute(&mut self, step: Step, key: K, func: F) -> Result<()> where + K: Into> + Debug, F: Fn() -> Result<()>, - M: Into> + Debug, { if !self.ctx.config().should_run(step) { return Ok(()); } - let key = key.into(); + let key: Cow<'a, str> = key.into(); debug!("Step {:?}", key); // alter the `func` to put it in a span @@ -46,13 +70,13 @@ impl<'a> Runner<'a> { loop { match func() { Ok(()) => { - self.report.push_result(Some((key, StepResult::Success))); + self.push_result(key, StepResult::Success); break; } Err(e) if e.downcast_ref::().is_some() => break, Err(e) if e.downcast_ref::().is_some() => { if self.ctx.config().verbose() || self.ctx.config().show_skipped() { - self.report.push_result(Some((key, StepResult::Skipped(e.to_string())))); + self.push_result(key, StepResult::Skipped(e.to_string())); } break; } @@ -73,14 +97,14 @@ impl<'a> Runner<'a> { }; if !should_retry { - self.report.push_result(Some(( + self.push_result( key, if ignore_failure { StepResult::Ignored } else { StepResult::Failure }, - ))); + ); break; } } diff --git a/src/step.rs b/src/step.rs index fc6421d3..a209b0e5 100644 --- a/src/step.rs +++ b/src/step.rs @@ -664,7 +664,7 @@ impl Step { WslUpdate => { #[cfg(windows)] - runner.execute(*self, "WSL", || windows::update_wsl(ctx))? + runner.execute(*self, "Update WSL", || windows::update_wsl(ctx))? } Xcodes => { diff --git a/src/terminal.rs b/src/terminal.rs index 64e41c32..6dbbf1dc 100644 --- a/src/terminal.rs +++ b/src/terminal.rs @@ -16,7 +16,7 @@ use tracing::{debug, error}; use which_crate::which; use crate::command::CommandExt; -use crate::report::StepResult; +use crate::runner::StepResult; static TERMINAL: LazyLock> = LazyLock::new(|| Mutex::new(Terminal::new()));