Skip to main content

zoi_core/
sysroot.rs

1/// Manages the "Sysroot" (System Root) for Zoi operations.
2///
3/// A Sysroot allows Zoi to operate on an external directory as if it were
4/// the primary system root (`/`). This is a powerful feature for:
5/// - Bootstrapping: Creating a bootable OS image or container from the
6///   outside.
7/// - Cross-Installation: Installing packages for an embedded system or
8///   another partition.
9/// - Isolation: Testing installations without affecting the current host
10///   system.
11///
12/// When a sysroot is set, Zoi transparently redirects all absolute and
13/// relative paths to reside within this target directory.
14use std::path::PathBuf;
15use std::sync::{OnceLock, RwLock};
16
17/// Provides thread-safe access to the optional global sysroot path.
18fn sysroot_store() -> &'static RwLock<Option<PathBuf>> {
19    static SYSROOT: OnceLock<RwLock<Option<PathBuf>>> = OnceLock::new();
20    SYSROOT.get_or_init(|| RwLock::new(None))
21}
22
23/// Sets or replaces the global sysroot path.
24pub fn set_sysroot(path: PathBuf) {
25    if let Ok(mut guard) = sysroot_store().write() {
26        *guard = Some(path);
27    }
28}
29
30/// Clears the global sysroot path.
31pub fn clear_sysroot() {
32    if let Ok(mut guard) = sysroot_store().write() {
33        *guard = None;
34    }
35}
36
37/// Returns the global sysroot path if it has been set.
38pub fn get_sysroot() -> Option<PathBuf> {
39    sysroot_store().read().ok().and_then(|g| g.clone())
40}
41
42/// Prepends the sysroot to the given path if a sysroot is set.
43/// If the path is absolute, it is made relative to the current root before
44/// joining.
45pub fn apply_sysroot(path: impl Into<PathBuf>) -> PathBuf {
46    let path = path.into();
47    if let Some(root) = get_sysroot() {
48        if path.is_absolute() {
49            let mut components = path.components();
50            components.next();
51            root.join(components.as_path())
52        } else {
53            root.join(path)
54        }
55    } else {
56        path
57    }
58}