ant_node/upgrade/cache_dir.rs
1//! Shared cache directory for upgrade artifacts.
2//!
3//! Multiple ant-node instances on the same machine share a single cache
4//! directory so that release metadata and downloaded binaries are fetched only
5//! once, reducing GitHub API calls and bandwidth.
6
7use crate::error::{Error, Result};
8use std::fs;
9use std::path::PathBuf;
10
11/// Return the shared upgrade cache directory, creating it on demand.
12///
13/// The path is `{data_dir}/upgrades/` where `data_dir` comes from
14/// `directories::ProjectDirs` (e.g. `~/.local/share/ant/upgrades/` on
15/// Linux).
16///
17/// # Errors
18///
19/// Returns an error if the platform data directory cannot be determined or
20/// the directory cannot be created.
21pub fn upgrade_cache_dir() -> Result<PathBuf> {
22 let project_dirs = directories::ProjectDirs::from("", "", "ant").ok_or_else(|| {
23 Error::Upgrade("Cannot determine platform data directory for upgrade cache".to_string())
24 })?;
25
26 let cache_dir = project_dirs.data_dir().join("upgrades");
27 fs::create_dir_all(&cache_dir)?;
28
29 Ok(cache_dir)
30}
31
32#[cfg(test)]
33#[allow(clippy::unwrap_used, clippy::expect_used)]
34mod tests {
35 use super::*;
36
37 /// Verify the function succeeds and returns a path ending in "upgrades".
38 ///
39 /// Note: this creates a real directory under the platform data dir.
40 /// Modifying env vars to isolate this requires `unsafe` (due to
41 /// `deny(unsafe_code)`), so we accept the minor side-effect.
42 #[test]
43 fn test_upgrade_cache_dir_returns_path() {
44 let dir = upgrade_cache_dir().unwrap();
45 assert!(dir.exists());
46 assert!(dir.ends_with("upgrades"));
47 }
48}