xianyun_executor/
datadir.rs1use std::path::{Path, PathBuf};
6
7const BASE_PATH: &str = ".local/share/xianyun";
8const LEGACY_BASE_PATH: &str = ".local/share/caproni";
13
14pub fn dir_in(home: &Path, profile: &str) -> Result<PathBuf, std::io::Error> {
29 let primary = home.join(BASE_PATH).join(profile);
30 if primary.is_dir() {
31 return Ok(primary);
32 }
33
34 let legacy = home.join(LEGACY_BASE_PATH).join(profile);
35 if legacy.is_dir() {
36 return Ok(legacy);
37 }
38
39 std::fs::create_dir_all(&primary)?;
40 Ok(primary)
41}
42
43pub fn pki_dir_in(home: &Path, profile: &str) -> Result<PathBuf, std::io::Error> {
45 get_or_create_sub_dir(home, profile, "pki")
46}
47
48pub fn certs_dir_in(home: &Path, profile: &str) -> Result<PathBuf, std::io::Error> {
50 get_or_create_sub_dir(home, profile, "certs.d")
51}
52
53pub fn k3d_registries_path_in(home: &Path, profile: &str) -> Result<PathBuf, std::io::Error> {
55 let dir = dir_in(home, profile)?;
56 Ok(dir.join("k3d-registries.yaml"))
57}
58
59fn get_or_create_sub_dir(
60 home: &Path,
61 profile: &str,
62 subdir: &str,
63) -> Result<PathBuf, std::io::Error> {
64 let dir = dir_in(home, profile)?.join(subdir);
65 std::fs::create_dir_all(&dir)?;
66 Ok(dir)
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72
73 #[test]
84 fn dir_creates_directory_under_local_share_xianyun() {
85 let tmp_dir = tempfile::tempdir().unwrap();
86
87 let d = dir_in(tmp_dir.path(), "myprofile").unwrap();
88 assert_eq!(d, tmp_dir.path().join(".local/share/xianyun/myprofile"));
89 assert!(d.is_dir());
90 }
91
92 #[test]
98 fn dir_prefers_xianyun_path_when_it_already_exists() {
99 let tmp_dir = tempfile::tempdir().unwrap();
100 std::fs::create_dir_all(tmp_dir.path().join(".local/share/xianyun/myprofile")).unwrap();
101 std::fs::create_dir_all(tmp_dir.path().join(".local/share/caproni/myprofile")).unwrap();
102
103 let d = dir_in(tmp_dir.path(), "myprofile").unwrap();
104 assert_eq!(d, tmp_dir.path().join(".local/share/xianyun/myprofile"));
105 }
106
107 #[test]
108 fn dir_falls_back_to_existing_caproni_path() {
109 let tmp_dir = tempfile::tempdir().unwrap();
110 std::fs::create_dir_all(tmp_dir.path().join(".local/share/caproni/myprofile")).unwrap();
111
112 let d = dir_in(tmp_dir.path(), "myprofile").unwrap();
113 assert_eq!(d, tmp_dir.path().join(".local/share/caproni/myprofile"));
114 }
115
116 #[test]
117 fn dir_creates_under_xianyun_when_neither_exists() {
118 let tmp_dir = tempfile::tempdir().unwrap();
119
120 let d = dir_in(tmp_dir.path(), "myprofile").unwrap();
121 assert_eq!(d, tmp_dir.path().join(".local/share/xianyun/myprofile"));
122 }
123
124 #[test]
125 fn dir_profile_scoping() {
126 let tmp_dir = tempfile::tempdir().unwrap();
127
128 let d = dir_in(tmp_dir.path(), "xianyun").unwrap();
129 assert_eq!(d, tmp_dir.path().join(".local/share/xianyun/xianyun"));
130 }
131
132 #[test]
133 fn dir_idempotent() {
134 let tmp_dir = tempfile::tempdir().unwrap();
135 let d1 = dir_in(tmp_dir.path(), "test").unwrap();
136 let d2 = dir_in(tmp_dir.path(), "test").unwrap();
137 assert_eq!(d1, d2);
138 }
139
140 #[test]
141 fn pki_dir_creates_subdirectory() {
142 let tmp_dir = tempfile::tempdir().unwrap();
143
144 let d = pki_dir_in(tmp_dir.path(), "xianyun").unwrap();
145 assert_eq!(d, tmp_dir.path().join(".local/share/xianyun/xianyun/pki"));
146 assert!(d.is_dir());
147 }
148
149 #[test]
150 fn certs_dir_creates_subdirectory() {
151 let tmp_dir = tempfile::tempdir().unwrap();
152
153 let d = certs_dir_in(tmp_dir.path(), "myprofile").unwrap();
154 assert_eq!(
155 d,
156 tmp_dir
157 .path()
158 .join(".local/share/xianyun/myprofile/certs.d")
159 );
160 assert!(d.is_dir());
161 }
162}