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

nordisk/facett

facett-core/examples/resolution_sweep.rs

//! **Does every repo in the constellation still RESOLVE?** — the ~4 s/repo sweep
//! that would have caught modgunn and ordning the day they broke.
//!
//! ```text
//! cargo run -p facett-core --example resolution_sweep -- ~/git
//! cargo run -p facett-core --example resolution_sweep -- ~/git/korp ~/git/nornir
//! ```
//!
//! Exits 1 and names each repo with cargo's own first line. Exits 0 when every
//! repo answers.
//!
//! **Why this is its own sweep and not a column in the compile-coverage one.** A
//! repo that does not resolve is not RED, it is ABSENT: cargo cannot enumerate
//! its targets, so a compile check has nothing to compile, a dep-graph tool has
//! no graph, and the warehouse indexer skips it. MEASURED 2026-08-23 — modgunn
//! (12 test targets) and ordning (10) had been unresolvable for nine days and
//! nothing in the constellation reported it. modgunn's cause was
//! `warehouse-sql = [..., "skade/sql"]` still naming a feature skade dropped on
//! 2026-08-14: a *resolution* error, which no amount of building can find.
//!
//! Given a single directory that is not itself a cargo repo, every immediate
//! child that is one is swept — so `-- ~/git` means "the constellation".

use std::path::PathBuf;

use facett_core::law;

fn main() {
    let args: Vec<String> = std::env::args().skip(1).collect();
    if args.is_empty() {
        eprintln!("usage: resolution_sweep <repo-or-parent-dir>...");
        std::process::exit(2);
    }

    let mut roots: Vec<PathBuf> = Vec::new();
    for a in &args {
        let p = PathBuf::from(a);
        if p.join("Cargo.toml").is_file() {
            roots.push(p);
            continue;
        }
        // A parent directory: sweep the repos inside it, sorted so two runs of
        // the same tree report in the same order.
        let mut kids: Vec<PathBuf> = std::fs::read_dir(&p)
            .unwrap_or_else(|e| panic!("cannot read {}: {e}", p.display()))
            .filter_map(Result::ok)
            .map(|e| e.path())
            .filter(|c| c.join("Cargo.toml").is_file())
            .collect();
        kids.sort();
        roots.extend(kids);
    }

    // An empty scan is not a pass. Nothing swept means the argument was wrong,
    // and reporting that as "all clear" is the exact false green this
    // constellation keeps finding.
    if roots.is_empty() {
        eprintln!("resolution sweep found NO cargo repos under {args:?} — nothing was checked");
        std::process::exit(2);
    }

    let bad = law::unresolvable(&roots);
    println!("resolution sweep: {} repo(s) checked, {} unresolvable", roots.len(), bad.len());
    for u in &bad {
        println!("  {}", u.describe());
    }
    if !bad.is_empty() {
        std::process::exit(1);
    }
}