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(())
}