Skip to main content

Mountain/IPC/WindServiceHandlers/Utilities/
UserdataDir.rs

1#![allow(non_snake_case, unused_variables, dead_code, unused_imports)]
2
3//! Canonical userdata base directory (Tauri `app_data_dir`) + first-access
4//! scaffolding. Seeded by `AppLifecycle::Dirs` so every `/User/...` URI the
5//! renderer emits lands under the bundle-identifier-qualified Application
6//! Support path VS Code's profile system expects.
7
8use crate::dev_log;
9
10/// Canonical userdata base directory, set once from Tauri's PathResolver.
11static USERDATA_BASE_DIR:std::sync::OnceLock<String> = std::sync::OnceLock::new();
12
13/// Lazy-init flag - `ensure_userdata_dirs` is idempotent; the flag skips
14/// the directory walk after the first successful pass.
15static USERDATA_INITIALIZED:std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
16
17pub fn set_userdata_base_dir(Path:String) { let _ = USERDATA_BASE_DIR.set(Path); }
18
19pub fn get_userdata_base_dir() -> String {
20	if let Some(Dir) = USERDATA_BASE_DIR.get() {
21		return Dir.clone();
22	}
23
24	if let Ok(Home) = std::env::var("HOME") {
25		#[cfg(target_os = "macos")]
26		return format!("{}/Library/Application Support/Land", Home);
27
28		#[cfg(target_os = "linux")]
29		return format!("{}/.local/share/Land", Home);
30	}
31
32	"/tmp/Land".to_string()
33}
34
35pub fn ensure_userdata_dirs() {
36	if USERDATA_INITIALIZED.swap(true, std::sync::atomic::Ordering::Relaxed) {
37		return;
38	}
39
40	let Base = get_userdata_base_dir();
41
42	let Dirs = [
43		format!("{}/User", Base),
44		format!("{}/User/globalStorage", Base),
45		format!("{}/User/profiles/__default__profile__", Base),
46		format!("{}/User/snippets", Base),
47		format!("{}/User/prompts", Base),
48		format!("{}/User/cacheHome", Base),
49		format!("{}/logs", Base),
50		format!("{}/User/workspaceStorage", Base),
51		format!(
52			"{}/CachedConfigurations/defaults/__default__profile__-configurationDefaultsOverrides",
53			Base
54		),
55	];
56
57	for Dir in &Dirs {
58		if let Err(E) = std::fs::create_dir_all(Dir) {
59			dev_log!("lifecycle", "Failed to create userdata dir {}: {}", Dir, E);
60		}
61	}
62
63	let DefaultFiles = [
64		(format!("{}/User/settings.json", Base), "{}"),
65		(format!("{}/User/keybindings.json", Base), "[]"),
66		(format!("{}/User/tasks.json", Base), "{}"),
67		(format!("{}/User/extensions.json", Base), "[]"),
68		(format!("{}/User/mcp.json", Base), "{}"),
69	];
70
71	for (FilePath, DefaultContent) in &DefaultFiles {
72		if !std::path::Path::new(FilePath).exists() {
73			if let Err(E) = std::fs::write(FilePath, DefaultContent) {
74				dev_log!("lifecycle", "Failed to create default file {}: {}", FilePath, E);
75			}
76		}
77	}
78
79	dev_log!("lifecycle", "userdata dirs initialized at: {}/User/", Base);
80}