xtask/src/main.rs
//! **znippy-zoomies' ONE build path** — `cargo xtask build --suite ORIGINAL
//! [--atom <a>]`.
//!
//! The entire body of the verb is
//! [`nornir_build_thing::suite_cli::run`](nornir_build_thing::suite_cli::run). This
//! file names no package, no bin, no feature string and no profile: everything it
//! builds comes from `.nornir/build-variants.toml`, so the declaration and the build
//! cannot drift apart the way `holger-build` (three hardcoded tiers, blind to the
//! other ten variants on disk) and `dwarves/src/service.rs` (a hand-written
//! `--features embed-nornir,server` against a declaration saying `embed-all,read-fat`)
//! did.
//!
//! ## What was here before: nothing
//!
//! Measured 2026-08-03: znippy-zoomies had **no xtask at all** and **no
//! `.nornir/build-variants.toml`**, while shipping five real CLI binaries
//! (`osm-katana`, `lbunzip2`, `lgz`, `ljar`, `lzip`). They were built by hand cargo,
//! spelled differently in whichever `.nornir/*.md` last mentioned them, and
//! `dwarves buildthing znippy-zoomies` had no delivery to ask for. Prose that names
//! a cargo invocation IS a declaration; the fix is one verb that reads the real one.
//!
//! ## Invoking it
//!
//! This crate is SELF-ROOTING (its own `[workspace]`), so `-p xtask` cannot see it
//! from the repo root and the `.cargo/config.toml` alias uses `--manifest-path`:
//!
//! ```text
//! cargo xtask build --suite ORIGINAL --list # resolve + print, build nothing
//! cargo xtask build --suite ORIGINAL # build all five atoms
//! cargo xtask build --suite ORIGINAL --atom lgz # build one
//! ```
//!
//! ## The gate: `cargo xtask buildgate`
//!
//! The build verb above builds what the declaration names. It cannot tell you about a
//! bin the declaration FORGOT — and MEASURED at `49c7bc6` this repo has the sharpest
//! case of that in the constellation: the root manifest is a `[package]` **and** a
//! `[workspace]` with no `default-members`, so cargo selects the root package alone,
//! the root package declares no bins, and a bare `cargo build --bins` at the repo root
//! builds **0 of 11** bin targets and exits 0.
//!
//! `cargo xtask buildgate` compiles every declared atom at its own features and goes
//! red *with the numbers*: bins declared vs bins actually built, and every
//! `tests/*.rs` that compiled to a binary holding zero tests. Its whole body is
//! [`nornir_build_thing::buildgate::cli::run`], shared with korp and facett.
//!
//! ```text
//! cargo xtask buildgate --list # the numbers, compiling nothing
//! cargo xtask buildgate # both arms, every atom
//! cargo xtask buildgate --atom lgz --arms bins # one atom while iterating
//! ```
use std::path::{Path, PathBuf};
use anyhow::{bail, Result};
use nornir_build_thing::suite_cli;
/// The repo root — the parent of this crate's directory.
///
/// Taken from `CARGO_MANIFEST_DIR` rather than the current directory so the verb
/// resolves the same declaration whether it is invoked through the `cargo xtask`
/// alias from the repo root or by path from anywhere else. A build verb that reads a
/// different file depending on where you stood is a second declaration again.
fn repo_root() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR"))
.parent()
.expect("xtask/ always has a parent")
.to_path_buf()
}
fn main() -> Result<()> {
let argv: Vec<String> = std::env::args().skip(1).collect();
match argv.first().map(String::as_str) {
Some("build") => {
let args = suite_cli::parse(&argv[1..])?;
let built = suite_cli::run(&repo_root(), &args)?;
if !args.list {
eprintln!("built: {}", built.join(", "));
}
Ok(())
}
// `cargo xtask buildgate` — THE build gate. Three lines here on purpose: the
// whole verb is `nornir_build_thing::buildgate::cli::run`, shared verbatim
// with korp and facett, so the gate cannot drift between the three repos that
// needed it (LAW 5).
Some("buildgate") => {
std::process::exit(nornir_build_thing::buildgate::cli::run(&repo_root(), &argv[1..]));
}
Some(other) => bail!("unknown verb '{other}'\n\n{}", suite_cli::USAGE),
None => bail!("{}", suite_cli::USAGE),
}
}