feat(nothooks): add phase-aware hook runner with setup-hook state tracking
This commit is contained in:
44
crates/nothooks/src/runner.rs
Normal file
44
crates/nothooks/src/runner.rs
Normal 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()),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user