1use std::path::PathBuf;
8
9use crate::error::{Error, Result};
10
11pub const ENV_BIN: &str = "STACKQL_MCP_BIN";
13pub const ENV_BUNDLE: &str = "STACKQL_MCP_BUNDLE";
15
16pub fn home_dir() -> Result<PathBuf> {
18 if let Some(home) = std::env::var_os("HOME").filter(|v| !v.is_empty()) {
19 return Ok(PathBuf::from(home));
20 }
21 if cfg!(windows) {
22 if let Some(profile) = std::env::var_os("USERPROFILE").filter(|v| !v.is_empty()) {
23 return Ok(PathBuf::from(profile));
24 }
25 }
26 Err(Error::NoHomeDir)
27}
28
29pub fn default_approot() -> Result<PathBuf> {
31 Ok(home_dir()?.join(".stackql"))
32}
33
34pub fn bin_cache_root() -> Result<PathBuf> {
36 Ok(default_approot()?.join("mcp-server-bin"))
37}
38
39pub fn bundle_cache_dir(version: &str, platform_key: &str) -> Result<PathBuf> {
42 Ok(bin_cache_root()?.join(version).join(platform_key))
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48
49 #[test]
50 fn cache_dir_matches_the_shared_layout() {
51 let dir = bundle_cache_dir("0.10.500", "linux-x64").unwrap();
52 let suffix: PathBuf = [".stackql", "mcp-server-bin", "0.10.500", "linux-x64"]
53 .iter()
54 .collect();
55 assert!(
56 dir.ends_with(&suffix),
57 "{} should end with {}",
58 dir.display(),
59 suffix.display()
60 );
61 }
62}