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::platform::cache::global_cache_root;
11use crate::types::{CommitHash, SourceName, SourceUrl};
12
13#[derive(Debug, Clone)]
15pub struct GlobalCache {
16 pub root: PathBuf,
17}
18
19impl GlobalCache {
20 pub fn new() -> Result<Self, MarsError> {
27 let root = global_cache_root()?;
28
29 let cache = Self { root };
30 std::fs::create_dir_all(cache.archives_dir())?;
31 std::fs::create_dir_all(cache.git_dir())?;
32 Ok(cache)
33 }
34
35 pub fn archives_dir(&self) -> PathBuf {
36 self.root.join("archives")
37 }
38
39 pub fn git_dir(&self) -> PathBuf {
40 self.root.join("git")
41 }
42}
43
44#[derive(Debug, Clone)]
46pub struct ResolvedRef {
47 pub source_name: SourceName,
48 pub version: Option<semver::Version>,
49 pub version_tag: Option<String>,
51 pub commit: Option<CommitHash>,
52 pub tree_path: PathBuf,
53}
54
55#[derive(Debug, Clone)]
57pub struct AvailableVersion {
58 pub tag: String,
59 pub version: semver::Version,
60 pub commit_id: String,
61}
62
63pub fn list_versions(
65 url: &SourceUrl,
66 cache: &GlobalCache,
67) -> Result<Vec<AvailableVersion>, MarsError> {
68 git::list_versions(url.as_ref(), cache)
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn global_cache_creates_directory() {
77 let cache = GlobalCache::new().unwrap();
78 assert!(cache.root.exists());
79 let expected_root = global_cache_root().unwrap();
80 assert_eq!(cache.root, expected_root);
81 assert!(cache.archives_dir().exists());
82 assert!(cache.git_dir().exists());
83 }
84
85 #[test]
86 fn global_cache_idempotent() {
87 let cache1 = GlobalCache::new().unwrap();
88 let cache2 = GlobalCache::new().unwrap();
89 assert_eq!(cache1.root, cache2.root);
90 assert!(cache1.root.exists());
91 }
92}