Skip to main content

storekit/
rig.rs

1use crate::fixtures;
2use crate::paths::App;
3use std::path::Path;
4
5const REFUSAL: &str = "rig: refusing to boot: a fixture is named but /tmp is not the tree's tmp/";
6
7pub fn guard(app: &App, data_dir: &Path) {
8    if let Err(error) = guard_at(
9        Path::new("/tmp/.rig"),
10        fixtures::requested(app).is_some(),
11        data_dir,
12    ) {
13        eprintln!("{error}");
14        std::process::exit(2);
15    }
16}
17
18pub fn guard_at(stamp: &Path, requested: bool, data_dir: &Path) -> Result<(), String> {
19    if !requested {
20        return Ok(());
21    }
22    let rig = std::fs::read_to_string(stamp).map_err(|_| REFUSAL.to_owned())?;
23    let rig = rig.trim();
24    if rig.is_empty() || !data_dir.starts_with(rig) {
25        return Err(REFUSAL.to_owned());
26    }
27    Ok(())
28}
29
30#[cfg(test)]
31mod tests {
32    use super::*;
33    use std::path::PathBuf;
34
35    fn scratch(tag: &str) -> tempfile::TempDir {
36        let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tmp/testscratch");
37        std::fs::create_dir_all(&root).unwrap();
38        tempfile::Builder::new()
39            .prefix(&format!("rig-{tag}-"))
40            .tempdir_in(root)
41            .unwrap()
42    }
43
44    #[test]
45    fn a_missing_stamp_refuses_a_fixture_boot() {
46        let holder = scratch("missing");
47        assert_eq!(
48            guard_at(&holder.path().join("missing"), true, holder.path()),
49            Err(REFUSAL.to_owned())
50        );
51    }
52
53    #[test]
54    fn a_data_dir_outside_the_stamped_rig_is_refused() {
55        let holder = scratch("outside");
56        let rig = holder.path().join("rig");
57        std::fs::create_dir_all(&rig).unwrap();
58        let stamp = holder.path().join("stamp");
59        std::fs::write(&stamp, rig.to_string_lossy().as_bytes()).unwrap();
60        assert_eq!(
61            guard_at(&stamp, true, &holder.path().join("elsewhere")),
62            Err(REFUSAL.to_owned())
63        );
64    }
65
66    #[test]
67    fn a_data_dir_under_the_stamped_rig_passes() {
68        let holder = scratch("inside");
69        let rig = holder.path().join("rig");
70        let data = rig.join("data");
71        std::fs::create_dir_all(&data).unwrap();
72        let stamp = holder.path().join("stamp");
73        std::fs::write(&stamp, format!("{}\n", rig.display())).unwrap();
74        assert_eq!(guard_at(&stamp, true, &data), Ok(()));
75    }
76
77    #[test]
78    fn no_fixture_named_needs_no_stamp() {
79        let holder = scratch("no-fixture");
80        assert_eq!(
81            guard_at(&holder.path().join("missing"), false, holder.path()),
82            Ok(())
83        );
84    }
85}