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

nordisk/edda

crates/nornir-build-thing/examples/escaping_siblings.rs

//! **What `[build.toolchain] siblings` must list for a checkout** — the sibling
//! repos this repo's `path = "../…"` dependencies actually reach into,
//! measured, one name per line.
//!
//! A thin door onto [`escaping_path_deps`], the function
//! [`CargoToolchain::check_escaping_path_deps`] already refuses by. The refusal
//! names the list, but only from inside a build that got far enough to run it;
//! a recipe author writing the declaration in the first place had to guess, and
//! a guessed list is either short (the container fails inside itself, where the
//! error says least) or long (mounting trees the build never reads, and
//! claiming them as inputs).
//!
//! ```text
//! cargo run -p nornir-build-thing --example escaping_siblings -- ~/git/skade
//! ```
//!
//! Each line is `<sibling>` followed by the manifests that reach into it, so
//! the list can be read as a claim about the source graph and not just copied.

use nornir_build_thing::cargo_container::escaping_path_deps;

fn main() {
    let root = std::path::PathBuf::from(
        std::env::args().nth(1).unwrap_or_else(|| ".".to_string()),
    );
    let parent = root.parent().unwrap_or(&root).to_path_buf();
    let mut by_sibling: std::collections::BTreeMap<String, Vec<String>> =
        std::collections::BTreeMap::new();
    for (manifest, dep, resolved) in escaping_path_deps(&root) {
        let where_ = format!("{} → {dep}", manifest.strip_prefix(&root).unwrap_or(&manifest).display());
        match resolved
            .strip_prefix(&parent)
            .ok()
            .and_then(|r| r.components().next().and_then(|c| c.as_os_str().to_str()))
        {
            // ABOVE the parent: a flat sibling mount cannot reproduce it, and
            // `check_escaping_path_deps` refuses it outright. Named, not dropped.
            None => by_sibling.entry("ABOVE-THE-PARENT".into()).or_default().push(where_),
            Some(sib) => by_sibling.entry(sib.to_string()).or_default().push(where_),
        }
    }
    for (sib, wheres) in &by_sibling {
        println!("{sib}  ({} dep(s))", wheres.len());
        for w in wheres.iter().take(4) {
            println!("    {w}");
        }
    }
    let names: Vec<String> = by_sibling.keys().map(|s| format!("{s:?}")).collect();
    println!("siblings: vec![{}]", names.join(", "));
}