sara-tasks 2.7.9

Sara — folder-aware task manager
use anyhow::Result;
use rusqlite::Connection;

use super::commands::{all_commands, nth_step};
use super::tick;
use crate::commands::guide::support::{shell, working_dir};
use crate::infrastructure::config::Config;
use crate::infrastructure::db;

pub fn verify(
    conn: &Connection,
    _cfg: &Config,
    id: &str,
    step: Option<usize>,
    run: bool,
    tick_on_pass: bool,
) -> Result<()> {
    let task = db::resolve_task(conn, id)?;
    let steps = db::get_steps(conn, &task.uuid, db::STEP_KIND_STEP)?;
    let acceptance = db::get_steps(conn, &task.uuid, db::STEP_KIND_ACCEPTANCE)?;
    let dir = working_dir(conn, &task.project);

    if tick_on_pass {
        return tick::run(conn, &task, &steps, &acceptance, step, dir.as_deref());
    }

    let cmds: Vec<String> = match step {
        Some(n) => {
            let s = nth_step(&steps, n)?;
            if s.verify_cmd.is_none() {
                println!("Step {n} has no verify command.");
            }
            s.verify_cmd.iter().cloned().collect()
        }
        None => all_commands(conn, &task, &steps, &acceptance)?,
    };

    if !acceptance.is_empty() && step.is_none() {
        println!("Acceptance criteria:");
        for (i, a) in acceptance.iter().enumerate() {
            let mark = if a.done { "[x]" } else { "[ ]" };
            println!("  {} {}. {}", mark, i + 1, a.text);
        }
    }

    if cmds.is_empty() {
        println!("No verification commands found.");
        return Ok(());
    }

    if run && db::ensure_started(conn, &task.uuid)? {
        println!("Task {} is now active.", task.id.unwrap_or(0));
    }

    for cmd in &cmds {
        if !run {
            println!("{cmd}");
            continue;
        }
        println!("$ {cmd}");
        match shell(cmd, dir.as_deref()).status() {
            Ok(s) if s.success() => println!("  ok: passed"),
            Ok(s) => println!("  exited with {}", s.code().unwrap_or(-1)),
            Err(e) => println!("  failed to run: {e}"),
        }
    }
    Ok(())
}