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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
use failure::{bail, Error};
use std::borrow::Borrow;
use std::collections::HashMap;
use std::env;
use std::fs;
use std::hash::Hash;
use std::io;
use std::path::Path;
pub const DISTRO: &'static str = "distro";
pub struct Facts(HashMap<String, String>);
impl Facts {
pub fn new(facts: impl IntoIterator<Item = (String, String)>) -> Self {
Facts(facts.into_iter().collect())
}
pub fn load() -> Result<Facts, Error> {
let mut facts = HashMap::new();
if let Some(distro) = detect_distro()? {
facts.insert(DISTRO.to_string(), distro);
}
return Ok(Facts(facts));
fn detect_distro() -> Result<Option<String>, Error> {
if metadata("/etc/redhat-release")?
.map(|m| m.is_file())
.unwrap_or(false)
{
return Ok(Some("fedora".to_string()));
}
if metadata("/etc/gentoo-release")?
.map(|m| m.is_file())
.unwrap_or(false)
{
return Ok(Some("gentoo".to_string()));
}
if metadata("/etc/debian_version")?
.map(|m| m.is_file())
.unwrap_or(false)
{
return Ok(Some("debian".to_string()));
}
if environ("OSTYPE")?
.map(|s| s.starts_with("darwin"))
.unwrap_or(false)
{
return Ok(Some("osx".to_string()));
}
Ok(None)
}
fn metadata<P: AsRef<Path>>(path: P) -> Result<Option<fs::Metadata>, Error> {
let p = path.as_ref();
let m = match fs::metadata(p) {
Ok(m) => m,
Err(e) => match e.kind() {
io::ErrorKind::NotFound => return Ok(None),
_ => bail!("failed to load file metadata: {}: {}", p.display(), e),
},
};
Ok(Some(m))
}
fn environ(key: &str) -> Result<Option<String>, Error> {
let value = match env::var(key) {
Ok(value) => value,
Err(env::VarError::NotPresent) => return Ok(None),
Err(e) => bail!("failed to load environment var: {}: {}", key, e),
};
Ok(Some(value))
}
}
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&str>
where
String: Borrow<Q>,
Q: Hash + Eq,
{
self.0.get(k).map(|s| s.as_str())
}
}