//! CLI for checking documentation coverage on files changed since a base branch. //! //! Usage: `source-map-check [--worktree ] [--base ]` //! //! 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. use source_map_gen::{CheckResult, check_files_ratcheted}; use std::path::{Path, PathBuf}; use std::process::Command; fn main() { let args: Vec = 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 = 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(); match check_files_ratcheted(&file_refs, worktree_path, &base) { 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 { args.windows(2).find(|w| w[0] == flag).map(|w| w[1].clone()) }