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 #[must_use]
21 pub fn gather() -> Self {
22 Self::gather_with_executor(&RealProcessExecutor)
23 }
24
25 pub fn gather_with_executor(executor: &dyn ProcessExecutor) -> Self {
27 let os = format!("{} {}", std::env::consts::OS, std::env::consts::ARCH);
28 let working_directory = std::env::current_dir()
29 .ok()
30 .map(|p| p.display().to_string());
31 let shell = std::env::var("SHELL").ok();
32
33 let git_version = executor
34 .execute("git", &["--version"], &[], None)
35 .ok()
36 .map(|o| o.stdout.trim().to_string());
37
38 let git_repo = executor
39 .execute("git", &["rev-parse", "--git-dir"], &[], None)
40 .map(|o| o.status.success())
41 .unwrap_or(false);
42
43 let git_branch = if git_repo {
44 executor
45 .execute("git", &["branch", "--show-current"], &[], None)
46 .ok()
47 .map(|o| o.stdout.trim().to_string())
48 } else {
49 None
50 };
51
52 let uncommitted_changes = if git_repo {
53 executor
54 .execute("git", &["status", "--porcelain"], &[], None)
55 .ok()
56 .map(|o| o.stdout.lines().count())
57 } else {
58 None
59 };
60
61 Self {
62 os,
63 working_directory,
64 shell,
65 git_version,
66 git_repo,
67 git_branch,
68 uncommitted_changes,
69 arch: std::env::consts::ARCH.to_string(),
70 }
71 }
72}