xtask/tests/free_tree_run.rs
//! `cargo xtask free-tree` (`xtask/src/paid_guard.rs`): the verdict over what `cargo
//! tree` printed for the default-feature `gunnar-server`, driven here through stand-in
//! `cargo` programs, so each verdict is reached from a listing written down in the test.
use std::os::unix::fs::PermissionsExt;
use std::path::{Path, PathBuf};
use xtask::paid_guard::run;
struct Scratch(PathBuf);
impl Drop for Scratch {
fn drop(&mut self) {
let _ = std::fs::remove_dir_all(&self.0);
}
}
/// A stand-in `cargo`: `tree … -i <name>` prints `chain`, any other `tree` prints
/// `listing`; `exit` is its exit code.
fn stand_in(dir: &Path, name: &str, listing: &str, chain: &str, exit: i32) -> String {
let p = dir.join(name);
std::fs::write(
&p,
format!(
"#!/bin/sh\nfor a in \"$@\"; do if [ \"$a\" = -i ]; then cat <<'CHAIN'\n{chain}CHAIN\nexit 0; fi; done\n\
[ {exit} -ne 0 ] && {{ echo 'error: no such package' >&2; exit {exit}; }}\ncat <<'TREE'\n{listing}TREE\n"
),
)
.unwrap();
std::fs::set_permissions(&p, std::fs::Permissions::from_mode(0o755)).unwrap();
p.display().to_string()
}
#[test]
fn the_free_server_passes_only_when_it_links_nothing_paid() {
let base = std::env::temp_dir().join(format!("gunnar-free-tree-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&base);
std::fs::create_dir_all(&base).unwrap();
let _s = Scratch(base.clone());
let root = base.join("gunnar");
std::fs::create_dir_all(&root).unwrap();
let free = format!(
"gunnar-server v3.0.0 ({r}/crates/gunnar-server)\ngunnar-core v3.0.0 ({r}/crates/gunnar-core)\n\
edda-admit v0.1.0 ({p}/edda/crates/admit)\nserde v1.0.200\nserde v1.0.200 (*)\n",
r = root.display(),
p = base.display()
);
assert!(
run(&root, &stand_in(&base, "free", &free, "", 0)),
"a free tree was refused"
);
let paid = format!("{free}monetize-impl-build-thing v0.4.0\ngunnar-ui-server v1.6.0 ({}/gunnar-ui/crates/gunnar-ui-server)\n", base.display());
let chain = "monetize-impl-build-thing v0.4.0\n└── gunnar-server v3.0.0\n";
assert!(
!run(&root, &stand_in(&base, "paid", &paid, chain, 0)),
"a paid crate passed the free tree"
);
let private = format!(
"{free}vetra-thing v0.1.0 ({}/monetize-impl/crates/vetra-thing)\n",
base.display()
);
assert!(
!run(&root, &stand_in(&base, "private", &private, "", 0)),
"a crate from a private checkout passed"
);
assert!(
!run(&root, &stand_in(&base, "broken", "", "", 101)),
"a tree cargo could not print passed"
);
assert!(
!run(&root, &base.join("no-such-cargo").display().to_string()),
"a cargo that is not there passed"
);
}