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

nordisk/monetize

xtask/src/fast.rs

//! **`cargo xtask fast --product <id>`** (A28 H14, lane N3): the fast test of a product, on
//! THIS checkout's monetize-fast (monetize v2.0 P1, A24 §8.2): its estate bought, paid, laid,
//! installed and paired by the real ONE box, its real box binaries in rootless containers,
//! then torn down; one receipt.
//!
//! What is the product's stays the product's: its checkout beside this one builds its box rows,
//! its container media and its guest, and calls `monetize-fast` from `../monetize` (holger's
//! `cargo xtask fast`, gunnar's `cargo xtask fast`). This table names only where that verb is;
//! the estate's names and media are the product's facts, read by monetize-fast from its guest.
//!
//! `cargo xtask fast --product <holger|gunnar> [--out DIR] [--budget-s N] [--twin-late-s N] [--no-build]`
//! (everything after `--product <id>` goes to the product's verb). On the host: it starts containers.

use std::path::{Path, PathBuf};
use std::process::Command;
use std::time::Instant;

/// One product the fast test runs: its id and the verb its own checkout carries.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct FastProduct {
    /// The product (`--product`), as the shop sells it.
    pub id: &'static str,
    /// Its checkout, beside this one.
    pub checkout: &'static str,
    /// The verb there (cargo's arguments).
    pub verb: &'static [&'static str],
}

/// **The declared table**: every product with a fast verb of its own.
pub const PRODUCTS: &[FastProduct] = &[
    FastProduct {
        id: "holger",
        checkout: "holger",
        verb: &["xtask", "fast"],
    },
    FastProduct {
        id: "gunnar",
        checkout: "gunnar",
        verb: &["xtask", "fast"],
    },
];

const USAGE: &str = "cargo xtask fast --product <holger|gunnar> [--out DIR] [--budget-s N] [--twin-late-s N] [--no-build]";

/// The parsed verb.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Args {
    pub product: &'static FastProduct,
    /// Handed to the product's verb as they are.
    pub rest: Vec<String>,
}

/// Parse `--product <id> [rest…]` (the flag may come anywhere).
pub fn parse(args: &[String]) -> Result<Args, String> {
    let at = args
        .iter()
        .position(|a| a == "--product")
        .ok_or_else(|| format!("which product? `{USAGE}`"))?;
    let id = args
        .get(at + 1)
        .ok_or_else(|| format!("--product wants a value; `{USAGE}`"))?;
    let product = PRODUCTS.iter().find(|p| p.id == id).ok_or_else(|| {
        let known = PRODUCTS.iter().map(|p| p.id).collect::<Vec<_>>().join(", ");
        if id == "lake" || id == "echo" {
            format!("[fast-product] the Lake lays no boxes of its own yet: its test is `cargo xtask bench lake`; the fast test runs {known}")
        } else {
            format!("[fast-product] `{id}` has no fast verb; the fast test runs {known}")
        }
    })?;
    let rest = args
        .iter()
        .enumerate()
        .filter(|(i, _)| *i != at && *i != at + 1)
        .map(|(_, a)| a.clone())
        .collect();
    Ok(Args { product, rest })
}

/// Pure: where the product's verb runs and its argv.
pub fn command(root: &Path, a: &Args) -> (PathBuf, Vec<String>) {
    let dir = root.parent().unwrap_or(root).join(a.product.checkout);
    let mut argv = vec!["cargo".to_string()];
    argv.extend(a.product.verb.iter().map(|s| s.to_string()));
    argv.extend(a.rest.iter().cloned());
    (dir, argv)
}

/// Pure: **the product's own target** under a shared one (`$CARGO_TARGET_DIR/fast-<product>`).
/// Both repos have a path package `xtask` of the same version, and cargo gives such a package
/// the same build hash in every checkout: under ONE target the product's launcher would run
/// monetize's xtask. `None`: no shared target, the product builds in its own default.
pub fn product_target(shared: Option<&Path>, product: &str) -> Option<PathBuf> {
    shared.map(|t| t.join(format!("fast-{product}")))
}

/// Run it; answers the wall time in seconds.
pub fn run(root: &Path, a: &Args) -> Result<u64, String> {
    let (dir, argv) = command(root, a);
    if !dir.join("Cargo.toml").is_file() {
        return Err(format!(
            "[fast-no-checkout] {}'s checkout is not beside monetize: {} (clone it there)",
            a.product.id,
            dir.display()
        ));
    }
    println!(
        "fast {}: {} (in {})",
        a.product.id,
        argv.join(" "),
        dir.display()
    );
    let t0 = Instant::now();
    let mut cmd = Command::new(std::env::var("CARGO").unwrap_or_else(|_| "cargo".into()));
    cmd.args(&argv[1..]).current_dir(&dir);
    let shared = std::env::var_os("CARGO_TARGET_DIR").map(PathBuf::from);
    match product_target(shared.as_deref(), a.product.id) {
        Some(t) => {
            println!("fast {}: its own target {}", a.product.id, t.display());
            cmd.env("CARGO_TARGET_DIR", t);
        }
        None => {
            cmd.env_remove("CARGO_TARGET_DIR");
        }
    }
    let status = cmd
        .status()
        .map_err(|e| format!("{}: {e}", argv.join(" ")))?;
    let secs = t0.elapsed().as_secs();
    if status.success() {
        Ok(secs)
    } else {
        Err(format!("[fast-red] the fast test of {} is RED after {secs} s ({status}); its receipt is under {}", a.product.id, dir.join("target/fast").display()))
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    /// ★ **A product's verb never shares our target** (2026-10-25): both repos have a path
    /// package `xtask` of the same version, and cargo gives such a package the same build hash
    /// in every checkout. Under one CARGO_TARGET_DIR the product's launcher ran OUR xtask
    /// ("which product?"). So the verb gets its own sub-target, inside a bounded one.
    #[test]
    fn the_products_verb_builds_in_its_own_target() {
        let t = product_target(Some(Path::new("/work/ci/target")), "holger");
        assert_eq!(t.as_deref(), Some(Path::new("/work/ci/target/fast-holger")));
        assert_ne!(
            product_target(Some(Path::new("/t")), "holger"),
            product_target(Some(Path::new("/t")), "gunnar"),
            "one per product"
        );
        assert_eq!(
            product_target(None, "holger"),
            None,
            "no shared target: the product's own default"
        );
    }
}