yoke/src/guard.rs

93 lines
2.7 KiB
Rust
Raw Normal View History

2026-02-26 05:46:41 +00:00
use std::fs;
use std::path::Path;
use std::process::Command;
2026-02-26 18:02:32 +00:00
#[allow(dead_code)]
2026-02-26 05:46:41 +00:00
pub struct GuardResult {
pub name: String,
pub passed: bool,
pub output: String,
pub skipped: bool,
}
/// Keep only the last `max` lines of text.
fn tail_lines(text: &str, max: usize) -> String {
let lines: Vec<&str> = text.lines().collect();
if lines.len() <= max {
return text.to_string();
}
lines[lines.len() - max..].join("\n")
}
/// Run all configured guard commands in order (fail-fast).
/// Writes results to `results_path` in markdown format.
pub fn run_guards(guards: &[String], max_tail: usize, results_path: &Path) -> Vec<GuardResult> {
let mut results = Vec::new();
let mut markdown = String::new();
let mut failed = false;
for cmd in guards {
if failed {
let result = GuardResult {
name: cmd.clone(),
passed: false,
output: String::new(),
skipped: true,
};
markdown.push_str(&format!("## {} — SKIPPED\n\n", cmd));
markdown.push_str("```\nSkipped due to earlier guard failure.\n```\n\n");
results.push(result);
continue;
}
let output = Command::new("sh")
.arg("-c")
.arg(cmd)
.output();
let (exit_ok, raw_output) = match output {
Ok(o) => {
let mut combined = String::from_utf8_lossy(&o.stdout).into_owned();
let stderr = String::from_utf8_lossy(&o.stderr);
if !stderr.is_empty() {
if !combined.is_empty() && !combined.ends_with('\n') {
combined.push('\n');
}
combined.push_str(&stderr);
}
(o.status.success(), combined)
}
Err(e) => (false, format!("failed to execute: {}", e)),
};
let truncated = tail_lines(&raw_output, max_tail);
let status_label = if exit_ok { "PASS" } else { "FAIL" };
markdown.push_str(&format!("## {} — {}\n\n", cmd, status_label));
markdown.push_str("```\n");
markdown.push_str(&truncated);
if !truncated.is_empty() && !truncated.ends_with('\n') {
markdown.push('\n');
}
markdown.push_str("```\n\n");
if !exit_ok {
failed = true;
}
results.push(GuardResult {
name: cmd.clone(),
passed: exit_ok,
output: truncated,
skipped: false,
});
}
// Write results file
if let Err(e) = fs::write(results_path, &markdown) {
eprintln!("[ci] WARNING: failed to write guard results: {}", e);
}
results
}