1use std::env;
10use std::fs;
11use std::path::PathBuf;
12
13fn legacy_dir() -> PathBuf {
15 let home = env::var("HOME").unwrap_or_default();
16 PathBuf::from(home).join(".cove")
17}
18
19pub fn state_dir() -> PathBuf {
21 env::var("XDG_STATE_HOME")
22 .map(PathBuf::from)
23 .unwrap_or_else(|_| {
24 let home = env::var("HOME").unwrap_or_default();
25 PathBuf::from(home).join(".local").join("state")
26 })
27 .join("cove")
28}
29
30pub fn events_dir() -> PathBuf {
32 state_dir().join("events")
33}
34
35pub fn migrate_legacy() {
41 let legacy = legacy_dir();
42 let xdg = state_dir();
43
44 if !legacy.is_dir() {
46 return;
47 }
48
49 if xdg.is_dir() {
51 return;
52 }
53
54 if let Some(parent) = xdg.parent() {
56 let _ = fs::create_dir_all(parent);
57 }
58
59 match fs::rename(&legacy, &xdg) {
61 Ok(()) => {
62 eprintln!(
63 "cove: migrated {} → {}",
64 legacy.display(),
65 xdg.display()
66 );
67 #[cfg(unix)]
69 {
70 let _ = std::os::unix::fs::symlink(&xdg, &legacy);
71 }
72 }
73 Err(e) => {
74 eprintln!(
76 "cove: could not migrate {} → {}: {e}",
77 legacy.display(),
78 xdg.display()
79 );
80 eprintln!("cove: continuing with {}", legacy.display());
81 }
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88
89 #[test]
90 fn state_dir_respects_xdg_env() {
91 unsafe { env::set_var("XDG_STATE_HOME", "/tmp/test-xdg-state") };
92 let dir = state_dir();
93 assert_eq!(dir, PathBuf::from("/tmp/test-xdg-state/cove"));
94 unsafe { env::remove_var("XDG_STATE_HOME") };
95 }
96
97 #[test]
98 fn events_dir_is_under_state() {
99 unsafe { env::set_var("XDG_STATE_HOME", "/tmp/test-xdg-state") };
100 let dir = events_dir();
101 assert_eq!(dir, PathBuf::from("/tmp/test-xdg-state/cove/events"));
102 unsafe { env::remove_var("XDG_STATE_HOME") };
103 }
104
105 #[test]
106 fn migrate_noop_when_no_legacy() {
107 unsafe { env::set_var("HOME", "/tmp/nonexistent-home-for-cove-test") };
108 unsafe { env::set_var("XDG_STATE_HOME", "/tmp/nonexistent-xdg-for-cove-test") };
109 migrate_legacy();
110 unsafe { env::remove_var("XDG_STATE_HOME") };
111 }
112}