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

nordisk/nornir

examples/dep_graph_demo.rs

//! Fast smoke demo: compute and persist a dep-graph snapshot.
//!
//!     cargo run --release --example dep_graph_demo
//!
//! Does NOT run cargo test or benches — just parses the workspace
//! TOML, walks each repo's Cargo.toml for produced/consumed crates,
//! builds the cross-repo edges, and writes them to the
//! `dep_graph_edges` Iceberg table. Useful as a wiring sanity check
//! before kicking off a full release.

use std::path::PathBuf;

use anyhow::{Context, Result};

use nornir::warehouse::dep_graph::{
    build as build_dep_graph, query_dep_graph_snapshots, record_dep_graph,
};
use nornir::warehouse::iceberg::IcebergWarehouse;
use nornir::workspace::descriptor::WorkspaceDescriptor;

fn main() -> Result<()> {
    let znippy = std::env::var("ZNIPPY_PATH")
        .map(PathBuf::from)
        .unwrap_or_else(|_| PathBuf::from(format!("/run/media/{}/T9/git/znippy", std::env::var("USER").unwrap_or_default())));
    let holger = std::env::var("HOLGER_PATH")
        .map(PathBuf::from)
        .unwrap_or_else(|_| PathBuf::from(format!("/run/media/{}/T9/git/holger", std::env::var("USER").unwrap_or_default())));

    let tmp = tempfile::tempdir().context("tempdir")?;
    let toml = format!(
        r#"[workspace]
name = "norninr-demo"

[repos.znippy]
path = "{}"

[repos.holger]
path = "{}"
"#,
        znippy.display(),
        holger.display()
    );
    let toml_path = tmp.path().join("nornir-workspace.toml");
    std::fs::write(&toml_path, toml)?;

    let desc = WorkspaceDescriptor::load(&toml_path)?;
    let graph = build_dep_graph(&desc)?;

    println!("📄 workspace `{}`", desc.workspace.name);
    println!("📚 repos:");
    for (name, facts) in &graph.facts {
        println!(
            "     {name:8}  produces=[{}] ({} crates)  consumes=[{}] ({} crates)",
            facts
                .produces
                .iter()
                .take(5)
                .cloned()
                .collect::<Vec<_>>()
                .join(", "),
            facts.produces.len(),
            facts
                .consumes
                .iter()
                .take(5)
                .cloned()
                .collect::<Vec<_>>()
                .join(", "),
            facts.consumes.len(),
        );
    }

    let order = graph.build_order()?;
    println!("\n🔗 build order: {order:?}");
    for e in &graph.edges {
        println!(
            "     {} → {}  via [{}]",
            e.from,
            e.to,
            e.via.iter().cloned().collect::<Vec<_>>().join(", ")
        );
    }

    let wh_root = PathBuf::from("/tmp/nornir-demo-warehouse");
    std::fs::create_dir_all(&wh_root)?;
    let wh = IcebergWarehouse::open(&wh_root)?;
    println!("\n📦 warehouse at {}", wh_root.display());

    let snap = wh.block_on(record_dep_graph(&wh, &desc.workspace.name, &graph))?;
    println!("📌 wrote snapshot {snap}");

    let all = wh.block_on(query_dep_graph_snapshots(&wh, &desc.workspace.name, None))?;
    println!(
        "\n🔎 total snapshots for `{}` in Urðr: {}",
        desc.workspace.name,
        all.len()
    );
    for s in all.iter().rev().take(3) {
        println!(
            "     {} @ {} — {} edges",
            s.snapshot_id,
            s.timestamp,
            s.edges.len()
        );
    }
    Ok(())
}