1use anyhow::{anyhow, bail, Result};
4use chrono::{TimeZone, Utc};
5use log::{debug, log, warn, Level};
6use std::env;
7use std::path::{Path, PathBuf};
8use std::time;
9
10pub fn source_date_epoch() -> Result<Option<i64>> {
11 let mut source_date_epoch = match env::var("SOURCE_DATE_EPOCH") {
12 Ok(val) => Some(val.parse::<i64>()?),
13 Err(_) => None,
14 };
15
16 if let Some(v) = source_date_epoch {
17 let now = time::SystemTime::now();
18 let now_sec = now.duration_since(time::UNIX_EPOCH).unwrap().as_secs();
19
20 let neg = v < 0;
21 let pos = v > 0 && v as u64 > now_sec;
22
23 log!(if neg || pos { Level::Warn } else { Level::Debug },
24 "SOURCE_DATE_EPOCH timestamp: {v} ({})",
25 Utc.timestamp_opt(v, 0).unwrap());
26 if neg {
27 warn!("SOURCE_DATE_EPOCH timestamp is negative, ignoring: {v}");
28 source_date_epoch = None;
29 } else if pos {
30 warn!("SOURCE_DATE_EPOCH timestamp is in the future: {v} > {now_sec}");
31 }
32 } else {
33 debug!("SOURCE_DATE_EPOCH timestamp: {}", "(unset)");
34 }
35
36 Ok(source_date_epoch)
37}
38
39pub fn brp_check(
40 build_root: Option<String>,
41 inputs: &Vec<PathBuf>,
42) -> Result<PathBuf> {
43
44 let build_root = build_root.map_or_else(
45 || env::var("RPM_BUILD_ROOT")
46 .map_err(|e| anyhow!("$RPM_BUILD_ROOT is not set correctly: {e}")),
47 Ok,
48 )?;
49
50 if build_root.is_empty() {
51 bail!("Empty $RPM_BUILD_ROOT is not allowed");
52 }
53
54 let build_root = PathBuf::from_iter(Path::new(&build_root).iter());
57
58 if build_root == Path::new("/") {
59 bail!("RPM_BUILD_ROOT={build_root:?} is not allowed");
60 }
61
62 for arg in inputs {
63 if !arg.starts_with(&build_root) {
64 bail!("Path {arg:?} does not start with RPM_BUILD_ROOT={build_root:?}");
65 }
66 }
67
68 Ok(build_root)
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn test_brp_check() {
77 let inputs = vec![
78 "/var/tmp/foo/bar".into(),
79 "/var/tmp/foo/./bar".into(),
80 "/var/tmp/foo/./bar/../asdf".into(),
82 "/var/tmp/foo/./bar/../../../asdf".into(),
83 ];
84
85 assert!(brp_check(Some("".to_string()), &inputs).is_err());
86 assert!(brp_check(Some("///.///".to_string()), &inputs).is_err());
87 assert!(brp_check(Some("/var/tmp/foo2".to_string()), &inputs).is_err());
88 assert!(brp_check(Some("/var/tmp/foo///./".to_string()), &inputs).is_ok());
89 }
90}