Skip to main content

kaizen/core/
paths.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2//! Shared path helpers (used by `workspace` and `machine_registry` to avoid import cycles).
3
4use std::path::{Path, PathBuf};
5
6/// `KAIZEN_HOME` or `~/.kaizen` (requires `HOME`), or `None` if undiscoverable.
7pub fn kaizen_dir() -> Option<PathBuf> {
8    std::env::var("KAIZEN_HOME")
9        .ok()
10        .map(PathBuf::from)
11        .or_else(|| {
12            std::env::var("HOME")
13                .ok()
14                .map(|home| PathBuf::from(home).join(".kaizen"))
15        })
16}
17
18pub fn canonical(path: &Path) -> PathBuf {
19    std::fs::canonicalize(path).unwrap_or_else(|_| absolute(path))
20}
21
22fn absolute(path: &Path) -> PathBuf {
23    if path.is_absolute() {
24        return path.to_path_buf();
25    }
26    std::env::current_dir()
27        .map(|cwd| cwd.join(path))
28        .unwrap_or_else(|_| path.to_path_buf())
29}
30
31#[cfg(test)]
32pub(crate) mod test_lock {
33    use std::sync::{Mutex, OnceLock};
34
35    static LOCK: OnceLock<Mutex<()>> = OnceLock::new();
36
37    pub fn global() -> &'static Mutex<()> {
38        LOCK.get_or_init(|| Mutex::new(()))
39    }
40}