//! `mock-render verify --project --section ` //! `mock-render status --project ` //! //! Two closely-related subcommands extracted from `main.rs` in v0.14.1. //! They share state-loading + hash-comparison logic. use crate::cli_args::{flag, require_project_section}; use crate::hash; use crate::state::SiteState; use std::path::{Path, PathBuf}; use std::process::ExitCode; pub fn run_verify(args: &[String]) -> ExitCode { let (project, section) = match require_project_section(args) { Ok(v) => v, Err(e) => { eprintln!("verify: {e}"); return ExitCode::from(1); } }; let st = match SiteState::load(&project) { Ok(s) => s, Err(e) => { eprintln!("verify: {e}"); return ExitCode::from(2); } }; let key = SiteState::key_for(§ion); let Some(entry) = st.sections.get(&key) else { eprintln!("verify: section '{key}' not in site-state.json (not locked yet)"); return ExitCode::SUCCESS; }; if !entry.locked { return ExitCode::SUCCESS; } let Ok(hash_now) = hash::hash_file(§ion) else { eprintln!("verify: cannot hash {}", section.display()); return ExitCode::from(2); }; if hash_now != entry.sha256 { eprintln!( "WYSIWYD VIOLATION: {key} drifted\n locked : {}\n current: {}\nThe screenshot user approved no longer matches the source.\nRerun render + user-approval before deploy.", &entry.sha256[..12], &hash_now[..12] ); return ExitCode::from(2); } println!("ok {key} ({})", &hash_now[..12]); ExitCode::SUCCESS } pub fn run_status(args: &[String]) -> ExitCode { let project = flag(args, "--project") .map(PathBuf::from) .unwrap_or_else(|| PathBuf::from(".")); let st = match SiteState::load(&project) { Ok(s) => s, Err(e) => { eprintln!("status: {e}"); return ExitCode::from(2); } }; if st.sections.is_empty() { println!("(no sections tracked)"); return ExitCode::SUCCESS; } for (name, sec) in &st.sections { let lock = if sec.locked { "LOCKED" } else { "open" }; let drift = match hash::hash_file(Path::new(&sec.path)) { Ok(h) if h == sec.sha256 => "clean", Ok(_) => "DRIFT", Err(_) => "missing", }; println!( "{:<20} {:>6} {:<7} {} ({})", name, lock, drift, sec.path, &sec.sha256[..12] ); } ExitCode::SUCCESS }