use crate::output_capture::Capture;
use std::process::Output;
use std::time::Duration;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum StepBound {
EndAt(Duration),
LeaveRunning {
after: Duration,
extra: Duration,
},
Unbounded,
}
#[derive(Debug)]
pub struct CeilingReached(
pub String,
);
impl std::fmt::Display for CeilingReached {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
return formatter.write_str(self.0.as_str());
}
}
impl std::error::Error for CeilingReached {}
pub(crate) fn output_of(status: std::process::ExitStatus, captured: Option<&Capture>) -> Output {
let Some(files) = captured else {
return Output { status, stdout: Vec::new(), stderr: Vec::new() };
};
let shown: crate::output_capture::Captured = files.snapshot(crate::output_capture::STEP_OUTPUT_LIMIT);
let mut stderr: Vec<u8> = shown.stderr;
for note in &shown.notes {
stderr.extend_from_slice(format!("\nmonochromatic-git-policy-cli: {note}\n").as_bytes());
}
files.discard();
return Output { status, stdout: shown.stdout, stderr };
}
pub fn not_known_text(waiting_for: &str, after: Duration, extra: Duration) -> String {
return format!(
"{waiting_for} was still running {} seconds after it began (its bound of {} seconds and {} more for the write it started), so it \
was left running and not ended: it is not known whether it finished. Check what it changes with `git status` and `git log -1`, \
look at the process with `ps` and at the disk it writes to, and run the command again if it did not finish.",
after.saturating_add(extra).as_secs(),
after.as_secs(),
extra.as_secs()
);
}
#[derive(Debug)]
pub struct NotKnown(
pub String,
);
impl std::fmt::Display for NotKnown {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
return formatter.write_str(self.0.as_str());
}
}
impl std::error::Error for NotKnown {}
pub fn is_not_known(error: &std::io::Error) -> bool {
return match error.get_ref() {
Some(inner) => inner.is::<NotKnown>(),
None => false,
};
}
pub fn is_ceiling(error: &std::io::Error) -> bool {
return match error.get_ref() {
Some(inner) => inner.is::<CeilingReached>(),
None => false,
};
}