holger-recipe/tests/open_declaration_without_monetize_impl.rs
//! **Holger's open declaration loads and lists without the commercial checkout.**
//!
//! Holger is open source: its open build must never NEED a monetize-impl checkout.
//! The sold payload's edge `plugin → monetize-impl/holger-guest : wasm` made the
//! shared load refuse the WHOLE declaration in a tree without monetize-impl, so
//! `cargo xtask build --list` died there (L15, 2026-10-18).
//!
//! Each test lays out a sibling tree in a temp dir: `holger` and every sibling of
//! this checkout as symlinks — except `monetize-impl`, which is absent, or a stub
//! donor the test writes itself.
use std::path::{Path, PathBuf};
use holger_recipe::load::{list, load_declaration, refuse_absent_commercial_donor};
use holger_recipe::packaging::{METERED_PAYLOAD_VARIANT, OWN_PLUGIN_REPO, OWN_PLUGIN_ROW};
use nornir_build_thing::suite_cli;
fn holger_root() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR"))
.parent()
.unwrap()
.to_path_buf()
}
/// A temp sibling tree; `holger` resolved through it. Removed on drop.
struct Tree(PathBuf);
impl Tree {
fn without_commercial(tag: &str) -> Self {
let dir =
std::env::temp_dir().join(format!("holger-open-decl-{tag}-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&dir);
std::fs::create_dir_all(&dir).unwrap();
let parent = holger_root().parent().unwrap().to_path_buf();
for entry in std::fs::read_dir(&parent).unwrap() {
let entry = entry.unwrap();
let name = entry.file_name();
if name == OWN_PLUGIN_REPO || !entry.path().is_dir() {
continue;
}
std::os::unix::fs::symlink(entry.path(), dir.join(&name)).unwrap();
}
assert!(dir.join("holger").is_dir());
assert!(!dir.join(OWN_PLUGIN_REPO).exists());
Tree(dir)
}
fn holger(&self) -> PathBuf {
self.0.join("holger")
}
/// A stub commercial donor declaring `holger-guest` as the given kind.
fn with_stub_donor(self, kind: &str) -> Self {
let nornir = self.0.join(OWN_PLUGIN_REPO).join(".nornir");
std::fs::create_dir_all(&nornir).unwrap();
std::fs::write(
nornir.join("build-variants.toml"),
format!(
"[[build.variant]]\nname = \"{OWN_PLUGIN_ROW}\"\nkind = \"{kind}\"\n\
target = \"wasm32-unknown-unknown\"\n"
),
)
.unwrap();
self
}
}
impl Drop for Tree {
fn drop(&mut self) {
let _ = std::fs::remove_dir_all(&self.0);
}
}
fn args(argv: &[&str]) -> suite_cli::BuildArgs {
suite_cli::parse(argv).unwrap()
}
#[test]
fn the_open_declaration_loads_without_monetize_impl() {
let tree = Tree::without_commercial("load");
let set = load_declaration(&tree.holger()).unwrap_or_else(|e| panic!("{e:#}"));
// The sold row and its edge stay in the declaration: lazy, not deleted.
let edges = set
.edges_of(METERED_PAYLOAD_VARIANT)
.expect("the sold row is declared");
assert!(
edges.iter().any(|(_, e)| e.repo == OWN_PLUGIN_REPO),
"{edges:?}"
);
}
#[test]
fn build_list_runs_without_monetize_impl() {
let tree = Tree::without_commercial("list");
// The one delivery lists; it names the sold row beside the open ones.
let (lines, names) = list(&tree.holger(), &args(&["--list", "--suite", "MVP"]))
.unwrap_or_else(|e| panic!("{e:#}"));
assert!(!lines.is_empty());
assert!(names.iter().any(|n| n == "mvp-server-musl"), "{names:?}");
assert!(
names.iter().any(|n| n == METERED_PAYLOAD_VARIANT),
"{names:?}"
);
for p in holger_recipe::variants::PRODUCTS {
assert!(
names.iter().any(|n| n == p),
"the product {p} is listed: {names:?}"
);
}
}
#[test]
fn building_the_sold_variant_without_monetize_impl_is_refused_by_name() {
let tree = Tree::without_commercial("refuse");
let set = load_declaration(&tree.holger()).unwrap_or_else(|e| panic!("{e:#}"));
let e = format!(
"{:#}",
refuse_absent_commercial_donor(&set, METERED_PAYLOAD_VARIANT, &tree.holger()).unwrap_err()
);
assert!(
e.contains(METERED_PAYLOAD_VARIANT) && e.contains(OWN_PLUGIN_REPO) && e.contains("SOLD"),
"{e}"
);
// Every open variant builds without it.
for open in [
"mvp-server-musl",
"holger",
"holger-downstream",
"holger-cli",
] {
refuse_absent_commercial_donor(&set, open, &tree.holger())
.unwrap_or_else(|e| panic!("{open}: {e:#}"));
}
}
#[test]
fn with_monetize_impl_present_the_edge_is_type_checked_and_the_sold_variant_builds() {
let ok = Tree::without_commercial("donor-ok").with_stub_donor("wasm");
let set = load_declaration(&ok.holger()).unwrap_or_else(|e| panic!("{e:#}"));
refuse_absent_commercial_donor(&set, METERED_PAYLOAD_VARIANT, &ok.holger()).unwrap();
// A donor whose row is the wrong typ is still refused at load.
let bad = Tree::without_commercial("donor-bad").with_stub_donor("exe");
let e = format!("{:#}", load_declaration(&bad.holger()).unwrap_err());
assert!(e.contains(OWN_PLUGIN_REPO), "{e}");
}
/// **No server row's container build needs holger-ui** (another checkout): only the estate
/// front's row and the console's own row reach it, so only those rows name it.
#[test]
fn open_rows_mount_no_holger_ui_and_only_the_front_row_names_it() {
let tree = Tree::without_commercial("siblings");
let root = tree.holger();
let set = load_declaration(&root).unwrap_or_else(|e| panic!("{e:#}"));
let tc = set
.toolchain
.clone()
.expect("holger declares its toolchain");
assert!(
!tc.siblings.iter().any(|s| s == "holger-ui"),
"{:?}",
tc.siblings
);
for open in [
"plugin-allocation",
"plugin-skidbladnir",
"plugin-rust-toolchain",
"mvp-server-musl",
] {
let v = set.get(open).unwrap();
assert!(
!tc.for_variant(v).siblings.iter().any(|s| s == "holger-ui"),
"{open}"
);
}
let front = set
.get(holger_recipe::packaging::FRONT_PAYLOAD_VARIANT)
.unwrap();
assert!(tc
.for_variant(front)
.siblings
.iter()
.any(|s| s == "holger-ui"));
let console = set.get(holger_recipe::variants::HOLGER_UI).unwrap();
assert!(tc
.for_variant(console)
.siblings
.iter()
.any(|s| s == "holger-ui"));
}