ralph_workflow/diagnostics/
system.rs1use crate::executor::{ProcessExecutor, RealProcessExecutor};
4
5#[derive(Debug, Clone)]
7pub struct SystemInfo {
8 pub os: String,
9 pub arch: String,
10 pub working_directory: Option<String>,
11 pub shell: Option<String>,
12 pub git_version: Option<String>,
13 pub git_repo: bool,
14 pub git_branch: Option<String>,
15 pub uncommitted_changes: Option<usize>,
16}
17
18impl SystemInfo {
19 pub fn gather() -> Self {
21 Self::gather_with_executor(&RealProcessExecutor)
22 }
23
24 pub fn gather_with_executor(executor: &dyn ProcessExecutor) -> Self {
26 let os = format!("{} {}", std::env::consts::OS, std::env::consts::ARCH);
27 let working_directory = std::env::current_dir()
28 .ok()
29 .map(|p| p.display().to_string());
30 let shell = std::env::var("SHELL").ok();
31
32 let git_version = executor
33 .execute("git", &["--version"], &[], None)
34 .ok()
35 .map(|o| o.stdout.trim().to_string());
36
37 let git_repo = executor
38 .execute("git", &["rev-parse", "--git-dir"], &[], None)
39 .map(|o| o.status.success())
40 .unwrap_or(false);
41
42 let git_branch = if git_repo {
43 executor
44 .execute("git", &["branch", "--show-current"], &[], None)
45 .ok()
46 .map(|o| o.stdout.trim().to_string())
47 } else {
48 None
49 };
50
51 let uncommitted_changes = if git_repo {
52 executor
53 .execute("git", &["status", "--porcelain"], &[], None)
54 .ok()
55 .map(|o| o.stdout.lines().count())
56 } else {
57 None
58 };
59
60 Self {
61 os,
62 working_directory,
63 shell,
64 git_version,
65 git_repo,
66 git_branch,
67 uncommitted_changes,
68 arch: std::env::consts::ARCH.to_string(),
69 }
70 }
71}