Files
huskies/crates/source-map-gen/src/main.rs
T

71 lines
2.3 KiB
Rust
Raw Normal View History

2026-04-28 21:02:00 +00:00
//! CLI for checking documentation coverage on files changed since a base branch.
//!
//! Usage: `source-map-check [--worktree <path>] [--base <branch>]`
//!
//! Exits with code 1 and prints LLM-friendly directions when public items are
//! missing doc comments. Exits 0 (silently) when all changed files are fully
//! documented or when there are no relevant changes to check.
2026-04-29 08:10:02 +00:00
use source_map_gen::{CheckResult, check_files_ratcheted};
2026-04-28 21:02:00 +00:00
use std::path::{Path, PathBuf};
use std::process::Command;
fn main() {
let args: Vec<String> = std::env::args().collect();
let worktree = parse_arg(&args, "--worktree").unwrap_or_else(|| ".".to_string());
let base = parse_arg(&args, "--base").unwrap_or_else(|| "master".to_string());
let worktree_path = Path::new(&worktree);
let output = match Command::new("git")
.args(["diff", "--name-only", &format!("{base}...HEAD")])
.current_dir(worktree_path)
.output()
{
Ok(o) => o,
Err(e) => {
eprintln!("source-map-check: git diff failed: {e}");
std::process::exit(1);
}
};
if !output.status.success() {
// Base branch not found or other git error — skip the check gracefully.
return;
}
let changed: Vec<PathBuf> = String::from_utf8_lossy(&output.stdout)
.lines()
.filter(|l| !l.is_empty())
.map(|l| worktree_path.join(l))
.filter(|p| p.exists())
.collect();
if changed.is_empty() {
return;
}
let file_refs: Vec<&Path> = changed.iter().map(PathBuf::as_path).collect();
2026-04-29 08:10:02 +00:00
match check_files_ratcheted(&file_refs, worktree_path, &base) {
2026-04-28 21:02:00 +00:00
CheckResult::Ok => {}
CheckResult::Failures(failures) => {
eprintln!(
"Doc coverage check failed. Add doc comments to the following items before committing:\n"
);
for f in &failures {
eprintln!(" {}", f.to_direction());
}
eprintln!(
"\nRe-run: cargo run -p source-map-gen --bin source-map-check -- --worktree . --base master"
);
std::process::exit(1);
}
}
}
/// Parse a flag value from an argument list (e.g. `--flag value`).
fn parse_arg(args: &[String], flag: &str) -> Option<String> {
args.windows(2).find(|w| w[0] == flag).map(|w| w[1].clone())
}