feat(nothooks): add phase-aware hook runner with setup-hook state tracking

This commit is contained in:
Joseph O'Brien
2026-03-31 17:26:26 -04:00
parent ed11aa9bc3
commit 4cc6fb022d
6 changed files with 262 additions and 1 deletions

View File

@@ -0,0 +1,44 @@
use std::path::PathBuf;
use std::process::Command;
use notcore::{HookPhase, HookSpec};
use crate::HookResult;
use crate::state::HookState;
pub struct HookRunner {
state_dir: PathBuf,
force: bool,
}
impl HookRunner {
pub fn new(state_dir: PathBuf) -> Self {
Self { state_dir, force: false }
}
pub fn with_force(state_dir: PathBuf) -> Self {
Self { state_dir, force: true }
}
pub fn run_hook(&self, spec: &HookSpec) -> HookResult {
let mut state = HookState::load(&self.state_dir).unwrap_or_default();
if spec.phase == HookPhase::Setup && !self.force && state.is_done(&spec.name) {
return HookResult::Skipped;
}
let result = Command::new("nu")
.arg(&spec.script)
.status();
match result {
Ok(status) if status.success() => {
if spec.phase == HookPhase::Setup {
state.mark_done(&spec.name);
let _ = state.save(&self.state_dir);
}
HookResult::Ok
}
Ok(status) => HookResult::Failed(format!("exit code {}", status.code().unwrap_or(-1))),
Err(e) => HookResult::Failed(e.to_string()),
}
}
}