kaizen/shell/
outcomes_cmd.rs1use crate::collect::outcomes;
5use crate::core::config;
6use crate::store::{SessionOutcomeRow, Store};
7use anyhow::{Context, Result};
8use std::path::Path;
9use std::time::Duration;
10
11pub fn cmd_outcomes_measure(workspace: &Path, session_id: &str) -> Result<()> {
13 let cfg = config::load(workspace)?;
14 let out = &cfg.collect.outcomes;
15 if !out.enabled {
16 return Ok(());
17 }
18 let store = Store::open(&crate::core::workspace::db_path(workspace)?)?;
19 let Some(session) = store.get_session(session_id).context("session not found")? else {
20 anyhow::bail!("session not in store");
21 };
22 let root = std::path::PathBuf::from(&session.workspace);
23 let tmo = Duration::from_secs(out.timeout_secs.max(1));
24 let m = outcomes::run_outcome_measure(&root, &out.test_cmd, out.lint_cmd.as_deref(), tmo);
25 let now = std::time::SystemTime::now()
26 .duration_since(std::time::UNIX_EPOCH)
27 .map(|d| d.as_millis() as u64)
28 .unwrap_or(0);
29 let row = SessionOutcomeRow {
30 session_id: session_id.to_string(),
31 test_passed: m.test_passed.map(|v| v as i64),
32 test_failed: m.test_failed.map(|v| v as i64),
33 test_skipped: m.test_skipped.map(|v| v as i64),
34 build_ok: None,
35 lint_errors: m.lint_errors.map(|v| v as i64),
36 revert_lines_14d: None,
37 pr_open: None,
38 ci_ok: None,
39 measured_at_ms: now,
40 measure_error: m.measure_error,
41 };
42 store.upsert_session_outcome(&row)?;
43 Ok(())
44}
45
46pub fn cmd_outcomes_show(id: &str, workspace: Option<&Path>) -> Result<()> {
48 let ws = workspace
49 .map(std::path::PathBuf::from)
50 .unwrap_or(std::env::current_dir()?);
51 let store = Store::open(&crate::core::workspace::db_path(&ws)?)?;
52 let r = store
53 .get_session_outcome(id)?
54 .context("no outcome for session")?;
55 print_row(&r);
56 Ok(())
57}
58
59fn print_row(r: &SessionOutcomeRow) {
60 let j = serde_json::json!({
61 "session_id": r.session_id,
62 "test_passed": r.test_passed,
63 "test_failed": r.test_failed,
64 "test_skipped": r.test_skipped,
65 "lint_errors": r.lint_errors,
66 "measured_at_ms": r.measured_at_ms,
67 "measure_error": r.measure_error,
68 });
69 println!("{}", serde_json::to_string_pretty(&j).unwrap_or_default());
70}