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	if let Ok(Home) = std::env::var("HOME") {
24		#[cfg(target_os = "macos")]
25		return format!("{}/Library/Application Support/Land", Home);
26		#[cfg(target_os = "linux")]
27		return format!("{}/.local/share/Land", Home);
28	}
29	"/tmp/Land".to_string()
30}
31
32pub fn ensure_userdata_dirs() {
33	if USERDATA_INITIALIZED.swap(true, std::sync::atomic::Ordering::Relaxed) {
34		return;
35	}
36
37	let Base = get_userdata_base_dir();
38	let Dirs = [
39		format!("{}/User", Base),
40		format!("{}/User/globalStorage", Base),
41		format!("{}/User/profiles/__default__profile__", Base),
42		format!("{}/User/snippets", Base),
43		format!("{}/User/prompts", Base),
44		format!("{}/User/cacheHome", Base),
45		format!("{}/logs", Base),
46		format!("{}/User/workspaceStorage", Base),
47		format!(
48			"{}/CachedConfigurations/defaults/__default__profile__-configurationDefaultsOverrides",
49			Base
50		),
51	];
52
53	for Dir in &Dirs {
54		if let Err(E) = std::fs::create_dir_all(Dir) {
55			dev_log!("lifecycle", "Failed to create userdata dir {}: {}", Dir, E);
56		}
57	}
58
59	let DefaultFiles = [
60		(format!("{}/User/settings.json", Base), "{}"),
61		(format!("{}/User/keybindings.json", Base), "[]"),
62		(format!("{}/User/tasks.json", Base), "{}"),
63		(format!("{}/User/extensions.json", Base), "[]"),
64		(format!("{}/User/mcp.json", Base), "{}"),
65	];
66
67	for (FilePath, DefaultContent) in &DefaultFiles {
68		if !std::path::Path::new(FilePath).exists() {
69			if let Err(E) = std::fs::write(FilePath, DefaultContent) {
70				dev_log!("lifecycle", "Failed to create default file {}: {}", FilePath, E);
71			}
72		}
73	}
74
75	dev_log!("lifecycle", "userdata dirs initialized at: {}/User/", Base);
76}