batuta/stack/releaser_preflight/
helpers.rs1use crate::stack::releaser::ReleaseOrchestrator;
6use crate::stack::types::PreflightCheck;
7use std::path::Path;
8use std::process::Command;
9
10pub fn run_check_command<F>(
19 config_command: &str,
20 check_id: &str,
21 skip_msg: &str,
22 crate_path: &Path,
23 process_output: F,
24) -> PreflightCheck
25where
26 F: FnOnce(&std::process::Output, &str, &str) -> PreflightCheck,
27{
28 let parts: Vec<&str> = config_command.split_whitespace().collect();
29 if parts.is_empty() {
30 return PreflightCheck::pass(check_id, skip_msg);
31 }
32 match Command::new(parts[0])
33 .args(parts.get(1..).unwrap_or(&[]))
34 .current_dir(crate_path)
35 .output()
36 {
37 Ok(output) => {
38 let stdout = String::from_utf8_lossy(&output.stdout).to_string();
39 let stderr = String::from_utf8_lossy(&output.stderr).to_string();
40 process_output(&output, &stdout, &stderr)
41 }
42 Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
43 PreflightCheck::pass(check_id, format!("{} not found (skipped)", parts[0]))
44 }
45 Err(e) => PreflightCheck::fail(check_id, format!("Failed to run {}: {}", parts[0], e)),
46 }
47}
48
49pub fn parse_value_from_json(json: &str, keys: &[&str]) -> Option<f64> {
51 keys.iter().find_map(|k| ReleaseOrchestrator::parse_score_from_json(json, k))
52}
53
54pub fn parse_count_from_json_multi(json: &str, keys: &[&str]) -> Option<u32> {
56 parse_value_from_json(json, keys).map(|f| f as u32)
57}
58
59pub fn score_check_result(
64 check_id: &str,
65 label: &str,
66 value: Option<f64>,
67 threshold: f64,
68 fail_on_threshold: bool,
69 status_success: bool,
70) -> PreflightCheck {
71 match value {
72 Some(v) if v >= threshold => PreflightCheck::pass(
73 check_id,
74 format!("{}: {:.1} (minimum: {:.1})", label, v, threshold),
75 ),
76 Some(v) if fail_on_threshold => PreflightCheck::fail(
77 check_id,
78 format!("{} {:.1} below minimum {:.1}", label, v, threshold),
79 ),
80 Some(v) => PreflightCheck::pass(
81 check_id,
82 format!("{}: {:.1} (warning: below {:.1})", label, v, threshold),
83 ),
84 None if status_success => PreflightCheck::pass(check_id, format!("{} check passed", label)),
85 None => {
86 PreflightCheck::pass(check_id, format!("{} check completed (score not parsed)", label))
87 }
88 }
89}