ggen_cli_lib/cmds/
utils.rs1use clap_noun_verb::Result;
6use clap_noun_verb_macros::verb;
7use serde::Serialize;
8use std::collections::HashMap;
9
10#[derive(Serialize)]
15struct DoctorOutput {
16 checks_passed: usize,
17 checks_failed: usize,
18 warnings: usize,
19 results: Vec<CheckResult>,
20 overall_status: String,
21}
22
23#[derive(Serialize)]
24struct CheckResult {
25 name: String,
26 status: String,
27 message: Option<String>,
28}
29
30#[derive(Serialize)]
31struct EnvOutput {
32 variables: HashMap<String, String>,
33 total: usize,
34}
35
36#[derive(Serialize)]
38#[allow(dead_code)]
39struct EnvSetOutput {
40 key: String,
41 value: String,
42 success: bool,
43}
44
45#[verb]
51fn doctor(all: bool, _fix: bool, format: Option<String>) -> Result<DoctorOutput> {
52 let format = format.unwrap_or_else(|| "table".to_string());
53 use ggen_core::domain::utils::{execute_doctor, DoctorInput};
54
55 let input = DoctorInput {
56 verbose: all,
57 check: None,
58 env: format == "env",
59 };
60
61 let result = crate::runtime::block_on(async move {
62 execute_doctor(input).await.map_err(|e| {
63 ggen_core::utils::error::Error::new(&format!("System diagnostics failed: {}", e))
64 })
65 })
66 .map_err(|e: ggen_core::utils::Error| {
67 clap_noun_verb::NounVerbError::execution_error(e.to_string())
68 })?
69 .map_err(|e: ggen_core::utils::Error| {
70 clap_noun_verb::NounVerbError::execution_error(e.to_string())
71 })?;
72
73 let results = result
74 .checks
75 .into_iter()
76 .map(|r| CheckResult {
77 name: r.name,
78 status: format!("{:?}", r.status),
79 message: Some(r.message),
80 })
81 .collect::<Vec<_>>();
82
83 let checks_passed = results.iter().filter(|r| r.status == "Ok").count();
84 let checks_failed = results.iter().filter(|r| r.status == "Error").count();
85 let warnings = results.iter().filter(|r| r.status == "Warning").count();
86
87 let overall_status = if checks_failed == 0 {
88 "healthy".to_string()
89 } else {
90 "needs attention".to_string()
91 };
92
93 Ok(DoctorOutput {
94 checks_passed,
95 checks_failed,
96 warnings,
97 results,
98 overall_status,
99 })
100}
101
102#[verb]
104fn env(list: bool, get: Option<String>, set: Option<String>, _system: bool) -> Result<EnvOutput> {
105 let variables = run_env(list, &get, &set);
106 let total = variables.len();
107 Ok(EnvOutput { variables, total })
108}
109
110fn run_env(list: bool, get: &Option<String>, set: &Option<String>) -> HashMap<String, String> {
111 let mut variables = HashMap::new();
112
113 if let Some(key) = get {
114 if let Ok(value) = std::env::var(key) {
115 variables.insert(key.clone(), value);
116 }
117 } else if let Some(kv) = set {
118 if let Some((key, value)) = kv.split_once('=') {
119 std::env::set_var(key, value);
120 variables.insert(key.to_string(), value.to_string());
121 }
122 }
123
124 if list || (get.is_none() && set.is_none()) {
125 collect_ggen_env_vars(&mut variables);
126 }
127
128 variables
129}
130
131fn collect_ggen_env_vars(vars: &mut HashMap<String, String>) {
132 for (key, value) in std::env::vars() {
133 if key.starts_with("GGEN_") || key.starts_with("RUST_") || key == "HOME" || key == "PATH" {
134 vars.insert(key, value);
135 }
136 }
137}