mars_agents/source/
mod.rs1pub(crate) mod archive;
2pub mod git;
3pub(crate) mod git_cli;
4pub mod parse;
5pub mod path;
6
7use std::path::PathBuf;
8
9use crate::error::MarsError;
10use crate::types::{CommitHash, SourceName, SourceUrl};
11
12#[derive(Debug, Clone)]
14pub struct GlobalCache {
15 pub root: PathBuf,
16}
17
18impl GlobalCache {
19 pub fn new() -> Result<Self, MarsError> {
26 let root = if let Some(cache_dir) = std::env::var_os("MARS_CACHE_DIR") {
27 PathBuf::from(cache_dir)
28 } else if let Some(home) = dirs::home_dir() {
29 home.join(".mars").join("cache")
30 } else {
31 std::env::current_dir()
32 .unwrap_or_else(|_| PathBuf::from("."))
33 .join(".mars")
34 .join("cache")
35 };
36
37 let cache = Self { root };
38 std::fs::create_dir_all(cache.archives_dir())?;
39 std::fs::create_dir_all(cache.git_dir())?;
40 Ok(cache)
41 }
42
43 pub fn archives_dir(&self) -> PathBuf {
44 self.root.join("archives")
45 }
46
47 pub fn git_dir(&self) -> PathBuf {
48 self.root.join("git")
49 }
50}
51
52#[derive(Debug, Clone)]
54pub struct ResolvedRef {
55 pub source_name: SourceName,
56 pub version: Option<semver::Version>,
57 pub version_tag: Option<String>,
59 pub commit: Option<CommitHash>,
60 pub tree_path: PathBuf,
61}
62
63#[derive(Debug, Clone)]
65pub struct AvailableVersion {
66 pub tag: String,
67 pub version: semver::Version,
68 pub commit_id: String,
69}
70
71pub fn list_versions(
73 url: &SourceUrl,
74 cache: &GlobalCache,
75) -> Result<Vec<AvailableVersion>, MarsError> {
76 git::list_versions(url.as_ref(), cache)
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[test]
84 fn global_cache_creates_directory() {
85 let cache = GlobalCache::new().unwrap();
86 assert!(cache.root.exists());
87 if let Some(from_env) = std::env::var_os("MARS_CACHE_DIR") {
88 assert_eq!(cache.root, PathBuf::from(from_env));
89 } else {
90 assert!(cache.root.ends_with(".mars/cache"));
91 }
92 assert!(cache.archives_dir().exists());
93 assert!(cache.git_dir().exists());
94 }
95
96 #[test]
97 fn global_cache_idempotent() {
98 let cache1 = GlobalCache::new().unwrap();
99 let cache2 = GlobalCache::new().unwrap();
100 assert_eq!(cache1.root, cache2.root);
101 assert!(cache1.root.exists());
102 }
103}