1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use kelpdot_macros::*;
use serde::{Deserialize, Serialize};
use std::path::Path;
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Os {
    /// Name of the os
    pub name: String,
    /// File used to reconise it
    pub file: String,
    /// "Priority" of the OS
    /// For example
    /// Arch has pritority 1 and file /etc/arch-release
    /// And manjaro has priority 2 and files /etc/arch-release AND /etc/manjaro-release
    /// If both /etc/manjaro-release and /etc/arch-release exists, the higher priority will be used
    /// In this case it's 2 (manjaro)
    pub priority: i16,
    /// The "pretty" name of the OS: for example "Arch GNU/Linux"
    pub prettyname: String,
    /// Submatches (parent distros)
    pub submatches: Vec<String>,
}
/// Find oses to detect
pub fn build_os_list() -> anyhow::Result<Vec<Os>> {
    let mut osyaml: Vec<Os> = vec![];
    let search_paths = vec!["/etc/kelpdot/os.yaml", "/etc/kelpdot/os.yml"];
    for path in search_paths {
        if Path::new(path).exists() {
            debug_print!("Reading OS file {}", path);
            let content = std::fs::read_to_string(path)?;
            let yaml: Vec<Os> = serde_yaml::from_str(&content)?;
            for os in yaml {
                osyaml.push(os);
            }
        }
    }
    debug_print!("Reading bundled OS file...");
    let bundled = include_str!("../../config/oses.yaml");
    let oses: Vec<Os> = serde_yaml::from_str(&bundled)?;
    for os in oses {
        osyaml.push(os);
    }
    Ok(osyaml)
}
/// Gets the host's OS
pub fn get_host_os() -> anyhow::Result<Os> {
    // Get a Vec<Os> wich is a list of reconisables oses
    let oses = build_os_list()?;
    let mut validoses: Vec<Os> = vec![];
    for system in oses {
        if Path::new(&system.file).exists() && system.name != "generic" {
            validoses.push(system);
        }
    }
    let mut sys: Os = Os {
        name: String::from("generic"),
        file: String::from("/"),
        priority: 0,
        prettyname: String::from("Generic GNU/Linux OS"),
        submatches: vec![],
    };
    for system in validoses {
        if sys.priority < system.priority {
            sys = system;
        }
    }
    Ok(sys)
}