//! Compiles style/main.scss into OUT_DIR and emits FORGE_BUILD_SHA for the binary. Each static //! asset also gets a content hash (FORGE_MAIN_CSS_V, FORGE_NAV_JS_V) that the page links use as //! their cache-busting query, so an unchanged file keeps its URL and a changed one gets a new one. use std::{env, fs, path::PathBuf}; use hex::encode; use sha2::{Digest, Sha256}; /// First 12 hex characters of the SHA-256 of `bytes`. fn content_version(bytes: &[u8]) -> String { encode(Sha256::digest(bytes))[..12].to_string() } fn main() { println!("cargo:rerun-if-env-changed=FORGE_BUILD_SHA"); println!("cargo:rerun-if-changed=../../style"); println!("cargo:rerun-if-changed=assets/nav.js"); let sha = env::var("FORGE_BUILD_SHA").unwrap_or_else(|_| "dev".to_string()); println!("cargo:rustc-env=FORGE_BUILD_SHA={sha}"); let manifest = PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR is set by cargo")); let out = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR is set by cargo")); let css = grass::from_path( manifest.join("../../style/main.scss"), &grass::Options::default(), ) .unwrap_or_else(|e| panic!("compiling style/main.scss: {e}")); println!( "cargo:rustc-env=FORGE_MAIN_CSS_V={}", content_version(css.as_bytes()) ); fs::write(out.join("main.css"), css).expect("writing compiled stylesheet to OUT_DIR"); let nav = fs::read(manifest.join("assets/nav.js")).expect("reading assets/nav.js"); println!("cargo:rustc-env=FORGE_NAV_JS_V={}", content_version(&nav)); }