Skip to main content

git_psect/commands/
pass_fail.rs

1use 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}