Files
topgrade/src/runner.rs

82 lines
2.5 KiB
Rust
Raw Normal View History

2020-02-09 13:41:55 +02:00
use crate::ctrlc;
2021-02-27 06:41:55 +02:00
use crate::error::{DryRun, SkipStep};
2020-02-09 13:41:55 +02:00
use crate::execution_context::ExecutionContext;
use crate::report::{Report, StepResult};
use crate::{config::Step, terminal::should_retry};
use anyhow::Result;
use log::debug;
2020-02-09 13:41:55 +02:00
use std::borrow::Cow;
use std::fmt::Debug;
pub struct Runner<'a> {
ctx: &'a ExecutionContext<'a>,
report: Report<'a>,
}
impl<'a> Runner<'a> {
pub fn new(ctx: &'a ExecutionContext) -> Runner<'a> {
Runner {
ctx,
report: Report::new(),
}
}
pub fn execute<F, M>(&mut self, step: Step, key: M, func: F) -> Result<()>
2020-02-09 13:41:55 +02:00
where
F: Fn() -> Result<()>,
M: Into<Cow<'a, str>> + Debug,
{
if !self.ctx.config().should_run(step) {
return Ok(());
}
2020-02-09 13:41:55 +02:00
let key = key.into();
debug!("Step {:?}", key);
loop {
match func() {
Ok(()) => {
self.report.push_result(Some((key, StepResult::Success)));
2020-02-09 13:41:55 +02:00
break;
}
2021-02-27 06:41:55 +02:00
Err(e) if e.downcast_ref::<DryRun>().is_some() => break,
2020-02-09 13:41:55 +02:00
Err(e) if e.downcast_ref::<SkipStep>().is_some() => {
2020-08-21 23:04:36 +03:00
if self.ctx.config().verbose() || self.ctx.config().show_skipped() {
self.report.push_result(Some((key, StepResult::Skipped(e.to_string()))));
}
2020-02-09 13:41:55 +02:00
break;
}
2021-01-15 06:16:28 +02:00
Err(e) => {
debug!("Step {:?} failed: {:?}", key, e);
2020-02-09 13:41:55 +02:00
let interrupted = ctrlc::interrupted();
if interrupted {
ctrlc::unset_interrupted();
}
let ignore_failure = self.ctx.config().ignore_failure(step);
let should_ask = interrupted || !(self.ctx.config().no_retry() || ignore_failure);
let should_retry = should_ask && should_retry(interrupted, key.as_ref())?;
2020-02-09 13:41:55 +02:00
if !should_retry {
self.report.push_result(Some((
key,
if ignore_failure {
StepResult::Ignored
} else {
StepResult::Failure
},
)));
2020-02-09 13:41:55 +02:00
break;
}
}
}
}
Ok(())
}
pub fn report(&self) -> &Report {
&self.report
}
}