git_psect/commands/
pass_fail.rs1use crate::{
2 candidates,
3 error::Error,
4 repo,
5 state::{self, Sample},
6};
7
8const CONFIDENCE_THRESHOLD: f64 = 0.95;
9
10pub fn run(outcome: bool, comment: Option<String>) -> Result<(), Error> {
11 let ctx = repo::open()?;
12 let mut state = state::read(&ctx.state_dir)?;
13
14 if state.old_revisions.is_empty() {
15 return Err(Error::Validation("run 'git psect old <rev>' first".into()));
16 }
17 if state.new_revisions.is_empty() {
18 return Err(Error::Validation("run 'git psect new <rev>' first".into()));
19 }
20
21 let head_sha = ctx.repo.head()?.peel_to_commit()?.id().to_string();
22
23 state.samples.push(Sample {
24 revision: head_sha.clone(),
25 outcome,
26 recorded_at: chrono::Utc::now().to_rfc3339(),
27 comment,
28 });
29 state::write(&ctx.state_dir, &state)?;
30
31 let verb = if outcome { "passed" } else { "failed" };
32 println!("{} {verb}.", &head_sha[..10]);
33
34 let candidates = candidates::build(&ctx.repo, &state)?;
35 let distributions = candidates::build_distributions(&state);
36 let ps = candidates::reconstruct(&ctx.repo, &state, &candidates, &distributions)?;
37
38 let confidence = ps.confidence();
39 let best = ps.most_likely_regression_revision().0.to_string();
40 let best_oid = ctx.repo.revparse_single(&best)?.id();
41 let best_summary = ctx
42 .repo
43 .find_commit(best_oid)?
44 .summary()
45 .unwrap_or("")
46 .to_string();
47
48 if confidence >= CONFIDENCE_THRESHOLD {
49 println!(
50 "{:.1}% chance of regression introduced in {}: {}",
51 confidence * 100.0,
52 &best[..10],
53 best_summary
54 );
55 println!(
56 "Run 'git psect reset' to clear the session or continue running tests to increase the confidence."
57 );
58 } else {
59 if confidence > 0.5 {
60 println!(
61 "Current best guess: {} ({:.1}% confidence).",
62 &best[..10],
63 confidence * 100.0
64 );
65 }
66 }
67 let next_sha = candidates::checkout_next(&ctx.repo, &distributions, &ps)?;
68 let next_summary = ctx
69 .repo
70 .find_commit(ctx.repo.revparse_single(&next_sha)?.id())?
71 .summary()
72 .unwrap_or("")
73 .to_string();
74 println!("Checking out {}: {}.", &next_sha[..10], next_summary);
75 println!("Hint: use 'git psect run <test>' to run on autopilot.");
76
77 Ok(())
78}