Fix "WSL already reported" panic (#1344)
This commit is contained in:
21
src/main.rs
21
src/main.rs
@@ -38,7 +38,6 @@ mod ctrlc;
|
|||||||
mod error;
|
mod error;
|
||||||
mod execution_context;
|
mod execution_context;
|
||||||
mod executor;
|
mod executor;
|
||||||
mod report;
|
|
||||||
mod runner;
|
mod runner;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
mod self_renamer;
|
mod self_renamer;
|
||||||
@@ -200,12 +199,19 @@ fn run() -> Result<()> {
|
|||||||
step.run(&mut runner, &ctx)?
|
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"));
|
print_separator(t!("Summary"));
|
||||||
|
|
||||||
for (key, result) in runner.report().data() {
|
for (key, result) in report {
|
||||||
|
if !failed && result.failed() {
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
print_result(key, result);
|
print_result(key, result);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
{
|
{
|
||||||
@@ -213,13 +219,12 @@ fn run() -> Result<()> {
|
|||||||
distribution.show_summary();
|
distribution.show_summary();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let mut post_command_failed = false;
|
|
||||||
if let Some(commands) = config.post_commands() {
|
if let Some(commands) = config.post_commands() {
|
||||||
for (name, command) in commands {
|
for (name, command) in commands {
|
||||||
if generic::run_custom_command(name, command, &ctx).is_err() {
|
let result = generic::run_custom_command(name, command, &ctx);
|
||||||
post_command_failed = true;
|
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() {
|
if !config.skip_notify() {
|
||||||
notify_desktop(
|
notify_desktop(
|
||||||
if failed {
|
if failed {
|
||||||
|
|||||||
@@ -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<M>(&mut self, result: Option<(M, StepResult)>)
|
|
||||||
where
|
|
||||||
M: Into<CowString<'a>>,
|
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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 color_eyre::eyre::Result;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use tracing::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> {
|
pub struct Runner<'a> {
|
||||||
ctx: &'a ExecutionContext<'a>,
|
ctx: &'a ExecutionContext<'a>,
|
||||||
report: Report<'a>,
|
report: Report<'a>,
|
||||||
@@ -19,20 +38,25 @@ impl<'a> Runner<'a> {
|
|||||||
pub fn new(ctx: &'a ExecutionContext) -> Runner<'a> {
|
pub fn new(ctx: &'a ExecutionContext) -> Runner<'a> {
|
||||||
Runner {
|
Runner {
|
||||||
ctx,
|
ctx,
|
||||||
report: Report::new(),
|
report: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute<F, M>(&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<K, F>(&mut self, step: Step, key: K, func: F) -> Result<()>
|
||||||
where
|
where
|
||||||
|
K: Into<Cow<'a, str>> + Debug,
|
||||||
F: Fn() -> Result<()>,
|
F: Fn() -> Result<()>,
|
||||||
M: Into<Cow<'a, str>> + Debug,
|
|
||||||
{
|
{
|
||||||
if !self.ctx.config().should_run(step) {
|
if !self.ctx.config().should_run(step) {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let key = key.into();
|
let key: Cow<'a, str> = key.into();
|
||||||
debug!("Step {:?}", key);
|
debug!("Step {:?}", key);
|
||||||
|
|
||||||
// alter the `func` to put it in a span
|
// alter the `func` to put it in a span
|
||||||
@@ -46,13 +70,13 @@ impl<'a> Runner<'a> {
|
|||||||
loop {
|
loop {
|
||||||
match func() {
|
match func() {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
self.report.push_result(Some((key, StepResult::Success)));
|
self.push_result(key, StepResult::Success);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Err(e) if e.downcast_ref::<DryRun>().is_some() => break,
|
Err(e) if e.downcast_ref::<DryRun>().is_some() => break,
|
||||||
Err(e) if e.downcast_ref::<SkipStep>().is_some() => {
|
Err(e) if e.downcast_ref::<SkipStep>().is_some() => {
|
||||||
if self.ctx.config().verbose() || self.ctx.config().show_skipped() {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
@@ -73,14 +97,14 @@ impl<'a> Runner<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if !should_retry {
|
if !should_retry {
|
||||||
self.report.push_result(Some((
|
self.push_result(
|
||||||
key,
|
key,
|
||||||
if ignore_failure {
|
if ignore_failure {
|
||||||
StepResult::Ignored
|
StepResult::Ignored
|
||||||
} else {
|
} else {
|
||||||
StepResult::Failure
|
StepResult::Failure
|
||||||
},
|
},
|
||||||
)));
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -664,7 +664,7 @@ impl Step {
|
|||||||
WslUpdate =>
|
WslUpdate =>
|
||||||
{
|
{
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
runner.execute(*self, "WSL", || windows::update_wsl(ctx))?
|
runner.execute(*self, "Update WSL", || windows::update_wsl(ctx))?
|
||||||
}
|
}
|
||||||
Xcodes =>
|
Xcodes =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use tracing::{debug, error};
|
|||||||
use which_crate::which;
|
use which_crate::which;
|
||||||
|
|
||||||
use crate::command::CommandExt;
|
use crate::command::CommandExt;
|
||||||
use crate::report::StepResult;
|
use crate::runner::StepResult;
|
||||||
|
|
||||||
static TERMINAL: LazyLock<Mutex<Terminal>> = LazyLock::new(|| Mutex::new(Terminal::new()));
|
static TERMINAL: LazyLock<Mutex<Terminal>> = LazyLock::new(|| Mutex::new(Terminal::new()));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user