1use std::path::PathBuf;
15
16pub fn runtime_dir() -> Option<PathBuf> {
19 if let Some(dir) = std::env::var_os("AUBE_RUNTIME_DIR")
20 && !dir.is_empty()
21 {
22 return Some(PathBuf::from(dir));
23 }
24 #[cfg(windows)]
25 if let Ok(local) = std::env::var("LOCALAPPDATA") {
26 return Some(PathBuf::from(local).join("aube/nodejs"));
27 }
28 let data_home = match aube_util::env::xdg_data_home() {
29 Some(xdg) => xdg,
30 None => aube_util::env::home_dir()?.join(".local/share"),
31 };
32 Some(data_home.join("aube/nodejs"))
33}
34
35pub fn install_dir(version: &node_semver::Version) -> Option<PathBuf> {
37 runtime_dir().map(|d| d.join(version.to_string()))
38}
39
40pub(crate) fn downloads_dir() -> Option<PathBuf> {
41 runtime_dir().map(|d| d.join(".downloads"))
42}
43
44pub(crate) fn staging_dir() -> Option<PathBuf> {
45 runtime_dir().map(|d| d.join(".tmp"))
46}
47
48pub(crate) fn locks_dir() -> Option<PathBuf> {
49 runtime_dir().map(|d| d.join(".locks"))
50}
51
52pub(crate) fn cache_dir() -> Option<PathBuf> {
55 if let Some(xdg) = aube_util::env::xdg_cache_home() {
56 return Some(xdg.join("aube"));
57 }
58 #[cfg(windows)]
59 if let Ok(local) = std::env::var("LOCALAPPDATA") {
60 return Some(PathBuf::from(local).join("aube"));
61 }
62 aube_util::env::home_dir().map(|h| h.join(".cache/aube"))
63}
64
65pub(crate) fn index_cache_path(mirror_base: &str) -> Option<PathBuf> {
69 cache_dir().map(|d| {
70 d.join("node-index")
71 .join(origin_segment(mirror_base))
72 .join("index.json")
73 })
74}
75
76pub(crate) fn shasums_cache_path(
80 mirror_base: &str,
81 version: &node_semver::Version,
82) -> Option<PathBuf> {
83 cache_dir().map(|d| {
84 d.join("node-shasums")
85 .join(origin_segment(mirror_base))
86 .join(format!("v{version}.txt"))
87 })
88}
89
90fn origin_segment(mirror_base: &str) -> String {
91 use sha2::Digest;
92 let digest = sha2::Sha256::digest(mirror_base.as_bytes());
93 format!("origin-{}", hex::encode(&digest[..8]))
94}