Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/holger-ui

crates/holger-ui-recipe/tests/estate_siblings.rs

//! **Every sibling the estate patches name is mounted into the build container.**
//!
//! The CI runner copies `.cargo/estate-siblings.toml` to `.cargo/siblings.toml`, so the
//! container's cargo reads its `[patch.crates-io]` paths. Each `../<repo>/…` path there
//! is only readable when `[build.toolchain] siblings` mounts `<repo>` beside the tree.
//!
//! RED in ODEN-CI round 1 (2026-10-25): `rows:MVP` died at `mvp-ui` with "failed to
//! read `/work/monetize/crates/monetize-estate-side/Cargo.toml`". The patch for
//! `monetize-estate-side` (5ff33dd) names `../monetize`, and the toolchain mounted
//! only `edda`.

use std::collections::BTreeSet;

use holger_ui_recipe::{declared, repo_root};

/// The `<repo>` of every `path = "../<repo>/…"` in the patch template.
fn patched_siblings(text: &str) -> BTreeSet<String> {
    text.lines()
        .map(str::trim)
        .filter(|l| !l.starts_with('#'))
        .filter_map(|l| l.split("path = \"../").nth(1))
        .filter_map(|rest| rest.split('/').next())
        .map(str::to_string)
        .collect()
}

#[test]
fn every_patched_sibling_is_a_declared_toolchain_sibling() {
    let path = repo_root().join(".cargo/estate-siblings.toml");
    let text = std::fs::read_to_string(&path).unwrap_or_else(|e| panic!("read {}: {e}", path.display()));
    let patched = patched_siblings(&text);
    assert!(!patched.is_empty(), "the template names no sibling; the check would be hollow");
    let mounted: BTreeSet<String> = declared()
        .toolchain
        .expect("the recipe declares [build.toolchain]")
        .siblings
        .into_iter()
        .collect();
    let missing: Vec<&String> = patched.difference(&mounted).collect();
    assert!(
        missing.is_empty(),
        "estate-siblings.toml patches from {missing:?}, but [build.toolchain] siblings mounts \
         only {mounted:?}: the container cannot read those paths"
    );
}

#[test]
fn the_reader_takes_the_repo_out_of_each_path() {
    let t = "# path = \"../holger/x\"\n[patch.crates-io]\na = { path = \"../edda/crates/a\" }\n\
             b = { path = \"../monetize/crates/b\" }\n";
    let got: Vec<String> = patched_siblings(t).into_iter().collect();
    assert_eq!(got, ["edda", "monetize"]);
}