aster_cli/commands/
info.rs1use anyhow::Result;
2use aster::config::paths::Paths;
3use aster::config::Config;
4use aster::session::session_manager::{DB_NAME, SESSIONS_FOLDER};
5use console::style;
6use serde_yaml;
7
8fn print_aligned(label: &str, value: &str, width: usize) {
9 println!(" {:<width$} {}", label, value, width = width);
10}
11
12use aster::config::base::CONFIG_YAML_NAME;
13use std::fs;
14use std::path::Path;
15
16fn check_path_status(path: &Path) -> String {
17 if path.exists() {
18 "".to_string()
19 } else {
20 let mut current = path.parent();
21 while let Some(parent) = current {
22 if parent.exists() {
23 return match fs::metadata(parent).map(|m| !m.permissions().readonly()) {
24 Ok(true) => style("missing (can create)").dim().to_string(),
25 Ok(false) => style("missing (read-only parent)").red().to_string(),
26 Err(_) => style("missing (cannot check)").red().to_string(),
27 };
28 }
29 current = parent.parent();
30 }
31 style("missing (no writable parent)").red().to_string()
32 }
33}
34
35pub fn handle_info(verbose: bool) -> Result<()> {
36 let logs_dir = Paths::in_state_dir("logs");
37 let sessions_dir = Paths::in_data_dir(SESSIONS_FOLDER);
38 let sessions_db = sessions_dir.join(DB_NAME);
39 let config = Config::global();
40 let config_dir = Paths::config_dir();
41 let config_yaml_file = config_dir.join(CONFIG_YAML_NAME);
42
43 let paths = [
44 ("Config dir:", &config_dir),
45 ("Config yaml:", &config_yaml_file),
46 ("Sessions DB (sqlite):", &sessions_db),
47 ("Logs dir:", &logs_dir),
48 ];
49
50 let label_padding = paths.iter().map(|(l, _)| l.len()).max().unwrap_or(0) + 4;
51 let path_padding = paths
52 .iter()
53 .map(|(_, p)| p.display().to_string().len())
54 .max()
55 .unwrap_or(0)
56 + 4;
57
58 println!("{}", style("aster Version:").cyan().bold());
59 print_aligned("Version:", env!("CARGO_PKG_VERSION"), label_padding);
60 println!();
61
62 println!("{}", style("Paths:").cyan().bold());
63 for (label, path) in &paths {
64 println!(
65 "{:<label_padding$}{:<path_padding$}{}",
66 label,
67 path.display(),
68 check_path_status(path)
69 );
70 }
71
72 if verbose {
73 println!("\n{}", style("aster Configuration:").cyan().bold());
74 let values = config.all_values()?;
75 if values.is_empty() {
76 println!(" No configuration values set");
77 println!(
78 " Run '{}' to configure aster",
79 style("aster configure").cyan()
80 );
81 } else {
82 let sorted_values: std::collections::BTreeMap<_, _> =
83 values.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
84
85 if let Ok(yaml) = serde_yaml::to_string(&sorted_values) {
86 for line in yaml.lines() {
87 println!(" {}", line);
88 }
89 }
90 }
91 }
92
93 Ok(())
94}