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

nordisk/gunnar

xtask/tests/container_robot_feature.rs

//! **L14: gunnar-server's container robot names edda's published `robot` feature itself.**
//!
//! `wg_appliance_core::robot` (the container-form ceremony robot's shared mechanics) is behind
//! wg-appliance-core's own `robot` feature (a test tool, A28 L14). Until wg-appliance-core 0.1.7
//! (R5D, 2026-10-27) the published crate had no such feature, so gunnar-server could not name it
//! and every run had to add `wg-appliance-core/robot` on the command line by hand. With the root
//! on crates.io (G-B7), the published feature is what a lone clone resolves, so the
//! `container-robot` feature turns it on and the command line names only `container-robot`.
//!
//! These read the tree only: no sibling, no network.

use std::path::{Path, PathBuf};

fn root() -> PathBuf {
    Path::new(env!("CARGO_MANIFEST_DIR"))
        .parent()
        .expect("xtask has a parent")
        .to_path_buf()
}

fn text(rel: &str) -> String {
    std::fs::read_to_string(root().join(rel)).unwrap_or_else(|e| panic!("{rel}: {e}"))
}

/// The first non-comment line of `manifest` whose key is `key`.
fn line_of<'a>(manifest: &'a str, key: &str) -> &'a str {
    manifest
        .lines()
        .find(|l| {
            let l = l.trim_start();
            !l.starts_with('#') && l.split_once('=').is_some_and(|(k, _)| k.trim() == key)
        })
        .unwrap_or_else(|| panic!("no `{key} = …` line"))
}

/// ★ L14: `container-robot` turns on `wg-appliance-core/robot`, and the dependency asks for the
/// first published line that has it (0.1.7).
#[test]
fn container_robot_turns_on_the_published_robot_feature() {
    let manifest = text("crates/gunnar-server/Cargo.toml");
    let feature = line_of(&manifest, "container-robot");
    assert!(
        feature.contains("\"wg-appliance-core/robot\""),
        "gunnar-server's `container-robot` must name `wg-appliance-core/robot` itself (published in 0.1.7): {feature}"
    );
    let dep = line_of(&manifest, "wg-appliance-core");
    assert!(
        dep.contains("version = \"0.1.7\""),
        "gunnar-server must ask for wg-appliance-core 0.1.7, the first published line with `robot`: {dep}"
    );
}

/// ★ L14: no word tells a reader to add the feature by hand, or that the published crate lacks it.
#[test]
fn no_word_says_the_robot_feature_is_given_by_hand() {
    for rel in [
        "crates/gunnar-server/Cargo.toml",
        "crates/gunnar-server/tests/appliance_container_robot.rs",
        "crates/gunnar-recipe/src/recipe.rs",
        ".nornir/build-variants.toml",
    ] {
        let t = text(rel);
        for stale in [
            "container-robot,wg-appliance-core/robot",
            "has no `robot` feature yet",
            "is not in the published wg-appliance-core",
        ] {
            assert!(!t.contains(stale), "{rel} still says `{stale}`: the published wg-appliance-core 0.1.7 has `robot`, and `container-robot` names it");
        }
    }
}