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