atagen

roundabout

public
Star0
Watch0
e9a5f5a41749831b9717b998d187ea5ca383b618
1
ssh://brewery@pls.lobotomise.me:33/atagen/roundabout.git
src/paths.rsRust89 lines2.4 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
    if let Some(p) = env::var_os("ROUNDABOUT_CONFIG") {
20
        return p.into();
21
    }
22
    let user = xdg("XDG_CONFIG_HOME", ".config").join("roundabout/config.toml");
23
    let system = PathBuf::from("/etc/roundabout/config.toml");
24
    if !user.exists() && system.exists() {
25
        system
26
    } else {
27
        user
28
    }
29
}
30
31
pub fn state_dir() -> PathBuf {
32
    let dir = env::var_os("ROUNDABOUT_STATE_DIR").map_or_else(
33
        || xdg("XDG_STATE_HOME", ".local/state").join("roundabout"),
34
        PathBuf::from,
35
    );
36
    let _ = fs::create_dir_all(&dir);
37
    dir
38
}
39
40
pub fn runtime_dir() -> PathBuf {
41
    if let Some(dir) = env::var_os("ROUNDABOUT_RUNTIME_DIR") {
42
        let dir = PathBuf::from(dir);
43
        let _ = fs::DirBuilder::new()
44
            .recursive(true)
45
            .mode(0o700)
46
            .create(&dir);
47
        return dir;
48
    }
49
    if let Some(dir) = env::var_os("XDG_RUNTIME_DIR").map(PathBuf::from)
50
        && dir.is_absolute()
51
        && dir.is_dir()
52
    {
53
        return dir;
54
    }
55
    let uid = unsafe { libc::getuid() };
56
    let dir = env::temp_dir().join(format!("roundabout-{uid}"));
57
    let _ = fs::DirBuilder::new().mode(0o700).create(&dir);
58
    let _ = fs::set_permissions(&dir, fs::Permissions::from_mode(0o700));
59
    dir
60
}
61
62
pub fn socket() -> PathBuf {
63
    runtime_dir().join("roundabout.sock")
64
}
65
66
pub fn spawn_lock() -> PathBuf {
67
    runtime_dir().join("roundabout.lock")
68
}
69
70
pub fn project_root(cwd: &Path) -> PathBuf {
71
    const MARKERS: [&str; 6] = [
72
        ".jj",
73
        ".git",
74
        ".hg",
75
        "flake.nix",
76
        "Cargo.toml",
77
        "package.json",
78
    ];
79
    let mut best = None;
80
    for dir in cwd.ancestors() {
81
        if dir.join(".jj").exists() || dir.join(".git").exists() || dir.join(".hg").exists() {
82
            return dir.to_path_buf();
83
        }
84
        if best.is_none() && MARKERS.iter().any(|m| dir.join(m).exists()) {
85
            best = Some(dir.to_path_buf());
86
        }
87
    }
88
    best.unwrap_or_else(|| cwd.to_path_buf())
89
}