xtask/src/main.rs
//! **modgunn's 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 contains no variant name, no feature string and no bin name: 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.
//!
//! modgunn had NO xtask, no CI config and no Makefile before 2026-08-01 — its build
//! recipes lived only in `.nornir/*.md` prose, three of which had drifted from the
//! TOML (a `service`/`ThinStandalone` variant "reaching the warehouse over gRPC" that
//! the declaration calls a plain `lib` reaching nothing). Prose that names a cargo
//! invocation IS a second declaration; the fix is one verb that reads the first.
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
/// works the same whether it is invoked through the `cargo xtask` alias from the
/// repo root or by path from anywhere else.
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(())
}
Some(other) => bail!("unknown verb '{other}'\n\n{}", suite_cli::USAGE),
None => bail!("{}", suite_cli::USAGE),
}
}