crates/gunnar-monetize-guest/build.rs
//! **The build reference, stamped into the module** (the guest compiles no proto since it
//! opens no door, monetize v2.0 P2 T13) as the custom section
//! [`SECTION`] — the SAME `git describe` gunnar-common stamps into every gunnar
//! binary (`GUNNAR_BUILD_REF`, same flags). The metered gunnar medium carries
//! this module inside gunnar-server, and gunnar-server refuses to register a
//! plugin whose stamp is not its own build reference: the plugin and the server
//! it speaks to are one commit, or the plugin is not offered at all. A custom
//! section is ignored by every wasm engine and covered by the signature like
//! every other byte.
use std::fmt::Write as _;
use std::path::PathBuf;
use std::process::Command;
/// The custom section the build reference is stamped into.
const SECTION: &str = "gunnar_build_ref";
/// The build reference, as gunnar-common computes it (same command, same
/// flags — see `crates/gunnar-common/build.rs` for why each `-c` is there),
/// `GUNNAR_BUILD_REF` when git cannot answer, else `unknown`.
fn build_ref() -> String {
let describe = Command::new("git")
.args([
"-c",
"safe.directory=*",
"-c",
"filter.lfs.required=false",
"-c",
"filter.lfs.process=",
"-c",
"filter.lfs.clean=",
"-c",
"filter.lfs.smudge=",
"-c",
"core.checkStat=minimal",
"describe",
"--tags",
"--always",
"--dirty=-modified",
"--abbrev=7",
])
.output()
.ok()
.filter(|o| o.status.success())
.map(|o| String::from_utf8_lossy(&o.stdout).trim().to_owned())
.filter(|s| !s.is_empty());
println!("cargo:rerun-if-env-changed=GUNNAR_BUILD_REF");
let from_env = std::env::var("GUNNAR_BUILD_REF")
.ok()
.map(|s| s.trim().to_owned())
.filter(|s| !s.is_empty());
describe.or(from_env).unwrap_or_else(|| {
println!("cargo:warning=gunnar-monetize-guest: no build reference (git describe failed, GUNNAR_BUILD_REF unset) — the module is stamped `unknown` and no gunnar-server will register it");
"unknown".to_owned()
})
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Read when the script RUNS, not when it was compiled: the target dir is
// shared across checkouts.
let manifest = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR")?);
// The stamp. HEAD moving is what changes it.
let git = manifest.join("../../.git");
println!("cargo:rerun-if-changed={}", git.join("HEAD").display());
println!("cargo:rerun-if-changed={}", git.join("index").display());
let r = build_ref();
let bytes = r.as_bytes();
let mut code = String::new();
let _ = writeln!(
code,
"/// This module's build reference (`git describe`, as gunnar-common stamps it)."
);
let _ = writeln!(code, "pub const BUILD_REF: &str = {r:?};");
let _ = writeln!(
code,
"/// The same bytes as the custom section `{SECTION}` — what gunnar-server reads back."
);
let _ = writeln!(code, "#[cfg(target_arch = \"wasm32\")]");
let _ = writeln!(code, "#[used]");
let _ = writeln!(code, "#[link_section = {SECTION:?}]");
let _ = writeln!(
code,
"static STAMPED_BUILD_REF: [u8; {}] = {bytes:?};",
bytes.len()
);
std::fs::write(
PathBuf::from(std::env::var("OUT_DIR")?).join("build_ref.rs"),
code,
)?;
Ok(())
}