1//! `LMJTFY_BUILD`: the commit the Worker is built from, with `-dirty` if the 2//! tree had changes, or `unknown` outside git. Every page carries it, and the 3//! archive object tells each page that connects what it is now: a page whose 4//! build differs is older than the site, and offers a reload. 5//! 6//! `LMJTFY_NOTE`: the built commit's `Release-Note:` trailer, or empty. A page 7//! from an earlier build is shown it as a toast when it reconnects after the 8//! deploy, so the people on the site hear what changed. 9 10//! 11//! `icons.rs` (in `OUT_DIR`): every picture in third-party/jerrys-pixel-icons 12//! by name, for the Worker to serve at `/icons/<name>.png`. 13 14use std::process::Command; 15 16fn git(args: &[&str]) -> Option<String> { 17 let output = Command::new("git").args(args).output().ok()?; 18 output.status.success().then(|| String::from_utf8_lossy(&output.stdout).trim().to_owned()) 19} 20 21fn main() { 22 let commit = git(&["rev-parse", "--short=12", "HEAD"]); 23 let dirty = git(&["status", "--porcelain"]).is_some_and(|status| !status.is_empty()); 24 let build = match commit { 25 Some(commit) if dirty => format!("{commit}-dirty"), 26 Some(commit) => commit, 27 None => "unknown".to_owned(), 28 }; 29 println!("cargo:rustc-env=LMJTFY_BUILD={build}"); 30 let note = git(&["log", "-1", "--format=%(trailers:key=Release-Note,valueonly,unfold)"]).unwrap_or_default(); 31 println!("cargo:rustc-env=LMJTFY_NOTE={}", note.lines().next().unwrap_or_default().trim()); 32 icons(); 33 // A new commit, or a change to what is staged, is a new build. 34 let root = git(&["rev-parse", "--show-toplevel"]).unwrap_or_default(); 35 for path in [".git/HEAD", ".git/index"] { 36 println!("cargo:rerun-if-changed={root}/{path}"); 37 } 38 if let Some(head) = git(&["symbolic-ref", "-q", "HEAD"]) { 39 println!("cargo:rerun-if-changed={root}/.git/{head}"); 40 } 41} 42 43/// Writes the table of icons: `("file-rust", include_bytes!(...))` for each 44/// PNG in the folder, sorted, so a name is found by binary search. 45fn icons() { 46 let folder = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("../../third-party/jerrys-pixel-icons"); 47 println!("cargo:rerun-if-changed={}", folder.display()); 48 let mut names: Vec<String> = std::fs::read_dir(&folder) 49 .expect("third-party/jerrys-pixel-icons is there") 50 .filter_map(|entry| entry.ok()?.file_name().into_string().ok()) 51 .filter_map(|name| name.strip_suffix(".png").map(str::to_owned)) 52 .collect(); 53 names.sort(); 54 let rows: String = names.iter().map(|name| format!(" ({name:?}, include_bytes!({:?})),\n", folder.join(format!("{name}.png")))).collect(); 55 let out = std::path::Path::new(&std::env::var("OUT_DIR").expect("cargo sets OUT_DIR")).join("icons.rs"); 56 std::fs::write(out, format!("pub static ICONS: &[(&str, &[u8])] = &[\n{rows}];\n")).expect("OUT_DIR can be written"); 57}