feature/ci-debian
rs 61 lines 1.8 KB
Raw
1 use home::home_dir;
2 use once_cell::sync::OnceCell;
3 use std::{fs, path::PathBuf};
4
5 /// Global runtime configuration for the Proses daemon and CLI.
6 ///
7 /// All paths are rooted under `~/.proses/`.
8 pub struct Config {
9 /// Persistent process store: `~/.proses/store.json`
10 pub store_path: PathBuf,
11 /// Unix domain socket used for IPC: `~/.proses/proses.sock`
12 pub sock_path: PathBuf,
13 /// Daemon PID file: `~/.proses/daemon.pid`
14 pub pid_path: PathBuf,
15 /// Directory for per-process stdout/stderr logs: `~/.proses/logs/`
16 pub log_dir: PathBuf,
17 }
18
19 static CONFIG: OnceCell<Config> = OnceCell::new();
20
21 /// Initialise the global [`Config`] singleton and create the necessary
22 /// directories on disk.
23 ///
24 /// Safe to call multiple times — subsequent calls are no-ops.
25 pub fn init() {
26 // If already initialised, nothing to do.
27 if CONFIG.get().is_some() {
28 return;
29 }
30
31 let base_dir = home_dir()
32 .expect("Cannot determine the home directory")
33 .join(".proses");
34
35 let log_dir = base_dir.join("logs");
36
37 fs::create_dir_all(&base_dir).expect("Failed to create ~/.proses directory");
38 fs::create_dir_all(&log_dir).expect("Failed to create ~/.proses/logs directory");
39
40 let config = Config {
41 store_path: base_dir.join("store.json"),
42 sock_path: base_dir.join("proses.sock"),
43 pid_path: base_dir.join("daemon.pid"),
44 log_dir,
45 };
46
47 // A concurrent caller may have beaten us to the set; that is fine —
48 // the value that wins is valid for our lifetime.
49 CONFIG.set(config).ok();
50 }
51
52 /// Return a reference to the global [`Config`].
53 ///
54 /// # Panics
55 /// Panics if [`init`] has not been called yet.
56 #[inline]
57 pub fn get() -> &'static Config {
58 CONFIG
59 .get()
60 .expect("Config not initialised — call config::init() first")
61 }