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

nordisk/knut

crates/knut-build-thing/src/emit.rs

//! **knut's half of the emitter** — `code → toml`, one-directional.
//!
//! The WRITER is `nornir_build_thing::emit` (one writer for every repo's recipe
//! crate); what lives here is this repo's own [`EMITTED_HEADER`] and the three
//! calls. The committed `.nornir/build-variants.toml` is [`emitted_toml`]'s
//! output and nothing else: an edit to it has ZERO effect on what the recipe
//! declares (`tests/toml_parity.rs` measures that), and the only way to change
//! the description is to change the code and re-emit.
//!
//! Until 2026-09-20 this direction ran the other way — `include_str!` +
//! `from_toml_str` — so there was no emitter at all and the file WAS the
//! declaration. The symlink that used to join `.nornir/build-variants.toml` to a
//! copy inside this crate is gone with it: it existed so `cargo package` could
//! reach the text that was compiled in, and nothing is compiled in any more.

use std::path::{Path, PathBuf};

use anyhow::Result;
use nornir_build_thing::emit;
use nornir_build_thing::plugin::BuildThing;

use crate::recipe::KnutBuild;

/// The header every emission starts with — says what the file is, and what it is
/// not.
pub const EMITTED_HEADER: &str = "\
# knut — .nornir/build-variants.toml — EMITTED, NOT SOURCE.
#
# Generated by `cargo run -p knut-build-thing -- emit` from
# crates/knut-build-thing (the Rust `impl BuildThing`). The code is the one
# source; this file DESCRIBES the build for readers and for the tools that
# discover a repo by this path. Editing it changes NOTHING: re-emit after
# changing the code. Do not edit by hand.
#
# Model: variant → features → settings/sub-settings → typ. Every row here is a
# CARGO row (typ exe or wasm), so the consequence of a toggle is the dep/feature
# CLOSURE delta — see `feature_table` / `consequence_of` in the recipe, which the
# tests hold to the member crates' own `[features]` tables.
#
# ⚠ THE TRAP THIS DECLARATION CLOSES: `cargo build --all-targets` SILENTLY SKIPS
# `required-features` binaries. FOUR of knut's five carry them (`bifrost` → cli,
# `knut-popviz` → gui, `knut-spark-server` → server, `graphar-flight` → bin; the
# fifth, `export-iceberg` → skade, is built by nothing and excused by name), so a
# plain build produces ONE of them and reports success. `[build.required]` below
# is that trap as data, and the recipe REFUSES a row that would emit nothing.";

/// The emission — what `.nornir/build-variants.toml` must contain.
pub fn emitted_toml() -> Result<String> {
    emit::emitted_toml(EMITTED_HEADER, &KnutBuild)
}

/// Regenerate `<repo_root>/.nornir/build-variants.toml` from the code.
pub fn write_emitted(repo_root: &Path) -> Result<PathBuf> {
    emit::write_emitted(EMITTED_HEADER, &KnutBuild, repo_root)
}

/// The repo root, from this crate's manifest directory.
#[must_use]
pub fn repo_root() -> PathBuf {
    Path::new(env!("CARGO_MANIFEST_DIR"))
        .parent()
        .and_then(Path::parent)
        .expect("crates/knut-build-thing has 2 ancestor(s)")
        .to_path_buf()
}

/// The set this recipe declares.
#[must_use]
pub fn declared() -> nornir_build_thing::variant::BuildVariantSet {
    KnutBuild.variants()
}