atagen

roundabout

public
Star0
Watch0
e50aca5650c22545f0d99db926ab1ae120f24699
1
ssh://brewery@pls.lobotomise.me:33/atagen/roundabout.git
src/paths.rsRust83 lines2.2 KB
1
use std::{
2
    env, fs,
3
    os::unix::fs::{DirBuilderExt, PermissionsExt},
4
    path::{Path, PathBuf},
5
};
6
7
fn home() -> PathBuf {
8
    env::var_os("HOME").map_or_else(|| PathBuf::from("/"), PathBuf::from)
9
}
10
11
fn xdg(var: &str, fallback: &str) -> PathBuf {
12
    env::var_os(var)
13
        .map(PathBuf::from)
14
        .filter(|p| p.is_absolute())
15
        .unwrap_or_else(|| home().join(fallback))
16
}
17
18
pub fn config_file() -> PathBuf {
19
    env::var_os("ROUNDABOUT_CONFIG").map_or_else(
20
        || xdg("XDG_CONFIG_HOME", ".config").join("roundabout/config.toml"),
21
        PathBuf::from,
22
    )
23
}
24
25
pub fn state_dir() -> PathBuf {
26
    let dir = env::var_os("ROUNDABOUT_STATE_DIR").map_or_else(
27
        || xdg("XDG_STATE_HOME", ".local/state").join("roundabout"),
28
        PathBuf::from,
29
    );
30
    let _ = fs::create_dir_all(&dir);
31
    dir
32
}
33
34
pub fn runtime_dir() -> PathBuf {
35
    if let Some(dir) = env::var_os("ROUNDABOUT_RUNTIME_DIR") {
36
        let dir = PathBuf::from(dir);
37
        let _ = fs::DirBuilder::new()
38
            .recursive(true)
39
            .mode(0o700)
40
            .create(&dir);
41
        return dir;
42
    }
43
    if let Some(dir) = env::var_os("XDG_RUNTIME_DIR").map(PathBuf::from)
44
        && dir.is_absolute()
45
        && dir.is_dir()
46
    {
47
        return dir;
48
    }
49
    let uid = unsafe { libc::getuid() };
50
    let dir = env::temp_dir().join(format!("roundabout-{uid}"));
51
    let _ = fs::DirBuilder::new().mode(0o700).create(&dir);
52
    let _ = fs::set_permissions(&dir, fs::Permissions::from_mode(0o700));
53
    dir
54
}
55
56
pub fn socket() -> PathBuf {
57
    runtime_dir().join("roundabout.sock")
58
}
59
60
pub fn spawn_lock() -> PathBuf {
61
    runtime_dir().join("roundabout.lock")
62
}
63
64
pub fn project_root(cwd: &Path) -> PathBuf {
65
    const MARKERS: [&str; 6] = [
66
        ".jj",
67
        ".git",
68
        ".hg",
69
        "flake.nix",
70
        "Cargo.toml",
71
        "package.json",
72
    ];
73
    let mut best = None;
74
    for dir in cwd.ancestors() {
75
        if dir.join(".jj").exists() || dir.join(".git").exists() || dir.join(".hg").exists() {
76
            return dir.to_path_buf();
77
        }
78
        if best.is_none() && MARKERS.iter().any(|m| dir.join(m).exists()) {
79
            best = Some(dir.to_path_buf());
80
        }
81
    }
82
    best.unwrap_or_else(|| cwd.to_path_buf())
83
}