use super::model::FixupMode;
use super::parse::FixupParser;
use crate::gate::{PendingFixupsResult, PendingFixupsStats};
use crate::orchestrator::OrchestratorHandle;
use std::path::PathBuf;
#[must_use]
pub fn pending_fixups_result_for_spec(spec_id: &str) -> PendingFixupsResult {
let spec_dir = PathBuf::from(".xchecker").join("specs").join(spec_id);
pending_fixups_result_impl(&spec_dir)
}
#[must_use]
pub fn pending_fixups_for_spec(spec_id: &str) -> PendingFixupsStats {
pending_fixups_result_for_spec(spec_id).into_stats()
}
fn pending_fixups_result_impl(base_path: &std::path::Path) -> PendingFixupsResult {
let review_md_path = base_path.join("artifacts").join("30-review.md");
if !review_md_path.exists() {
return PendingFixupsResult::None; }
let review_content = match std::fs::read_to_string(&review_md_path) {
Ok(content) => content,
Err(e) => {
return PendingFixupsResult::Unknown {
reason: format!("Failed to read review artifact: {}", e),
};
}
};
let fixup_parser = match FixupParser::new(FixupMode::Preview, base_path.to_path_buf()) {
Ok(parser) => parser,
Err(e) => {
return PendingFixupsResult::Unknown {
reason: format!("Failed to create fixup parser: {}", e),
};
}
};
if !fixup_parser.has_fixup_markers(&review_content) {
return PendingFixupsResult::None; }
match fixup_parser.parse_diffs(&review_content) {
Ok(diffs) => {
if diffs.is_empty() {
return PendingFixupsResult::None;
}
let targets = diffs.len() as u32;
let mut est_added: u32 = 0;
let mut est_removed: u32 = 0;
for diff in &diffs {
for hunk in &diff.hunks {
for line in hunk.content.lines() {
if line.starts_with('+') && !line.starts_with("+++") {
est_added = est_added.saturating_add(1);
} else if line.starts_with('-') && !line.starts_with("---") {
est_removed = est_removed.saturating_add(1);
}
}
}
}
PendingFixupsResult::Some(PendingFixupsStats {
targets,
est_added,
est_removed,
})
}
Err(e) => {
PendingFixupsResult::Unknown {
reason: format!("Review has fixup markers but diff parse failed: {}", e),
}
}
}
}
#[must_use]
pub fn pending_fixups_result_from_handle(handle: &OrchestratorHandle) -> PendingFixupsResult {
pending_fixups_result_for_spec(handle.spec_id())
}