xtask/tests/free_tree.rs
//! **RED-when-broken: gunnar's tree names no paid crate** (the owner, 2026-10-08).
//!
//! Every outside service has ONE seam in open monetize, a FREE impl there and a commercial one
//! in monetize-impl; the dependency points one way and gunnar never names monetize-impl. This
//! gate walks every manifest and every lockfile of the tree — the detached workspaces included —
//! and fails on any paid crate, or any path into monetize-impl.
//!
//! LEGACY (ONE monetize, owner 2026-10-10 13:35Z): `gunnar-front-commercial`, the paid front
//! built from monetize-impl with an estate's own monetize in it, is gone — the metered front is
//! gunnar's own `gunnar-front --features metered`, which links no monetize. The name stays in
//! the paid list so it can never come back into gunnar's tree.
use std::path::{Path, PathBuf};
use xtask::one_clone::{lockfiles, manifests};
/// The crates monetize-impl publishes to nobody: what an open gunnar build may never name.
const PAID: &[&str] = &[
"monetize-server-vetra",
"monetize-cloud-impl",
"monetize-pay-impl",
"monetize-signup-impl",
"monetize-tax-impl",
"monetize-product-njord",
"monetize-plugin-holger",
"gunnar-front-commercial",
"gunnar-shop-bench",
];
fn root() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR"))
.parent()
.expect("xtask has a parent")
.to_path_buf()
}
/// Pure: **the paid names a manifest's text depends on** — a `<name> =` key, a
/// `[dependencies.<name>]` table, or a `path` into `monetize-impl`. Comment lines are prose.
fn paid_in_manifest(text: &str) -> Vec<String> {
let mut out = Vec::new();
for line in text.lines().map(str::trim).filter(|l| !l.starts_with('#')) {
let line = line.split(" #").next().unwrap_or(line);
for name in PAID {
let key = line
.split('=')
.next()
.unwrap_or("")
.trim()
.trim_matches('"');
let table = line.trim_start_matches('[').trim_end_matches(']');
if key == *name || table.ends_with(&format!(".{name}")) {
out.push((*name).to_string());
}
}
if line.contains("path") && line.contains("monetize-impl") {
out.push(format!("a path into monetize-impl: {line}"));
}
}
out
}
/// Pure: the paid packages a lockfile holds.
fn paid_in_lock(text: &str) -> Vec<String> {
PAID.iter()
.filter(|n| text.contains(&format!("name = \"{n}\"")))
.map(|n| (*n).to_string())
.collect()
}
#[test]
fn gunnars_tree_names_no_paid_crate() {
let root = root();
let (ms, ls) = (manifests(&root), lockfiles(&root));
assert!(
ms.len() > 20 && ms.iter().any(|m| m.starts_with("crates/gunnar-growbench")),
"the walk sees the tree, detached crates included: {}",
ms.len()
);
let mut found = Vec::new();
for m in &ms {
for p in paid_in_manifest(&std::fs::read_to_string(root.join(m)).unwrap_or_default()) {
found.push(format!("{m}: {p}"));
}
}
for l in &ls {
for p in paid_in_lock(&std::fs::read_to_string(root.join(l)).unwrap_or_default()) {
found.push(format!("{l}: {p}"));
}
}
assert!(
found.is_empty(),
"gunnar's tree names paid crates — a paid crate lives in monetize-impl, never here:\n {}",
found.join("\n ")
);
}
/// The red half: each shape is SEEN, and prose that forbids it is not mistaken for it.
#[test]
fn a_paid_dependency_is_reported_in_each_shape() {
assert_eq!(paid_in_manifest("monetize-server-vetra = { path = \"../../../monetize-impl/crates/monetize-server-vetra\" }").len(), 2);
assert_eq!(
paid_in_manifest("[dependencies.monetize-cloud-impl]\nversion = \"0.1\""),
vec!["monetize-cloud-impl".to_string()]
);
assert_eq!(
paid_in_manifest("x = { path = \"../../monetize-impl/crates/y\" }").len(),
1
);
assert!(paid_in_manifest(
"# monetize-server-vetra = { path = \"../monetize-impl\" } is never named here"
)
.is_empty());
assert!(
paid_in_manifest(
"monetize-server = { path = \"../../../monetize/crates/monetize-server\" }"
)
.is_empty(),
"the OPEN server is fine"
);
assert_eq!(
paid_in_lock("[[package]]\nname = \"monetize-pay-impl\"\n"),
vec!["monetize-pay-impl".to_string()]
);
}