doum_cli/system/
env.rs

1use std::env;
2use std::path::PathBuf;
3
4/// OS 타입
5#[derive(Debug, Clone, PartialEq)]
6pub enum OsType {
7    Windows,
8    Linux,
9    MacOS,
10}
11
12/// 쉘 타입
13#[derive(Debug, Clone, PartialEq)]
14pub enum ShellType {
15    Cmd,
16    PowerShell,
17    Bash,
18    Zsh,
19    Fish,
20    Unknown,
21}
22
23/// 시스템 정보
24#[derive(Debug, Clone)]
25pub struct SystemInfo {
26    pub os: OsType,
27    pub shell: ShellType,
28    pub current_dir: PathBuf,
29    pub username: Option<String>,
30    pub hostname: Option<String>,
31}
32
33/// 현재 시스템 정보 수집
34pub fn get_system_info() -> SystemInfo {
35    SystemInfo {
36        os: detect_os(),
37        shell: detect_shell(),
38        current_dir: env::current_dir().unwrap_or_else(|_| PathBuf::from(".")),
39        username: env::var("USERNAME").or_else(|_| env::var("USER")).ok(),
40        hostname: env::var("COMPUTERNAME")
41            .or_else(|_| env::var("HOSTNAME"))
42            .ok(),
43    }
44}
45
46/// OS 타입 감지
47pub fn detect_os() -> OsType {
48    #[cfg(target_os = "windows")]
49    return OsType::Windows;
50
51    #[cfg(target_os = "linux")]
52    return OsType::Linux;
53
54    #[cfg(target_os = "macos")]
55    return OsType::MacOS;
56
57    #[cfg(not(any(target_os = "windows", target_os = "linux", target_os = "macos")))]
58    return OsType::Linux; // 기본값
59}
60
61/// 현재 쉘 감지
62pub fn detect_shell() -> ShellType {
63    // Windows에서는 ComSpec 환경 변수 확인
64    if cfg!(target_os = "windows") {
65        if let Ok(comspec) = env::var("COMSPEC")
66            && comspec.to_lowercase().contains("cmd.exe")
67        {
68            return ShellType::Cmd;
69        }
70
71        // PSModulePath가 있으면 PowerShell
72        if env::var("PSModulePath").is_ok() {
73            return ShellType::PowerShell;
74        }
75
76        return ShellType::Cmd; // Windows 기본값
77    }
78
79    // Unix 계열에서는 SHELL 환경 변수 확인
80    if let Ok(shell) = env::var("SHELL") {
81        let shell_lower = shell.to_lowercase();
82
83        if shell_lower.contains("bash") {
84            return ShellType::Bash;
85        } else if shell_lower.contains("zsh") {
86            return ShellType::Zsh;
87        } else if shell_lower.contains("fish") {
88            return ShellType::Fish;
89        }
90    }
91
92    // 부모 프로세스 이름으로 추가 확인 시도 (간단한 방법)
93    // 실제로는 더 정교한 감지가 필요할 수 있음
94
95    ShellType::Unknown
96}
97
98impl OsType {
99    /// OS 이름 문자열 반환
100    pub fn as_str(&self) -> &str {
101        match self {
102            OsType::Windows => "Windows",
103            OsType::Linux => "Linux",
104            OsType::MacOS => "macOS",
105        }
106    }
107}
108
109impl ShellType {
110    /// 쉘 이름 문자열 반환
111    pub fn as_str(&self) -> &str {
112        match self {
113            ShellType::Cmd => "cmd.exe",
114            ShellType::PowerShell => "PowerShell",
115            ShellType::Bash => "bash",
116            ShellType::Zsh => "zsh",
117            ShellType::Fish => "fish",
118            ShellType::Unknown => "unknown",
119        }
120    }
121}
122
123impl SystemInfo {
124    /// 시스템 정보를 사람이 읽기 쉬운 형태로 출력
125    pub fn display(&self) -> String {
126        format!(
127            "OS: {}\nShell: {}\nCurrent Dir: {}\nUsername: {}\nHostname: {}",
128            self.os.as_str(),
129            self.shell.as_str(),
130            self.current_dir.display(),
131            self.username.as_deref().unwrap_or("(unknown)"),
132            self.hostname.as_deref().unwrap_or("(unknown)")
133        )
134    }
135}