Something went wrong. Try again.
atproto Thingiverse but good
Something went wrong. Try again.
polymodel build.rs
3.9 kB · 94 lines
Rust
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495//! Build script.//!//! Reads `.env` and bakes any `POLYMODEL_*` variables into `src/env.rs` as//! compile-time constants. This is how configuration reaches the WASM bundle,//! which has no filesystem or process environment to read at runtime.//!//! Server-side runtime configuration (DATABASE_URL, HYDRANT_*) is NOT handled//! here: the server binary loads `.env` directly via `dotenvy` and reads it into//! a typed `ServerConfig` struct (see `src/indexing/config.rs`).
use serde_json::Value;use std::env;use std::fs::{self, File};use std::io::Write;use std::path::{Path, PathBuf};
fn main() { println!("cargo:rerun-if-changed=.env");
dotenvy::dotenv().ok();
let mut f = File::create("./src/env.rs").expect("create src/env.rs"); f.write_all( b"// This file is automatically generated by build.rs.\n\ // Frontend (WASM) compile-time configuration.\n\ // Do not edit; regenerate by rebuilding.\n", ) .expect("write env.rs header");
// Bake every POLYMODEL_* env var into the bundle as a `&'static str` const. for (key, value) in env::vars() { if let Some(rest) = key.strip_prefix("POLYMODEL_") { if rest.is_empty() { continue; } let line = format!( "#[allow(unused)]\npub const {}: &str = \"{}\";\n", key, value.replace('\\', "\\\\").replace('"', "\\\"") ); f.write_all(line.as_bytes()).expect("write env.rs const"); } } generate_indexed_collections();}fn generate_indexed_collections() { println!("cargo:rerun-if-changed=lexicons"); let lexicon_root = Path::new("lexicons"); let mut json_paths = Vec::new(); collect_json_paths(lexicon_root, &mut json_paths); json_paths.sort(); let mut collections = Vec::new(); for path in json_paths { println!("cargo:rerun-if-changed={}", path.display()); let contents = fs::read_to_string(&path) .unwrap_or_else(|e| panic!("read authored lexicon {}: {e}", path.display())); let lexicon: Value = serde_json::from_str(&contents) .unwrap_or_else(|e| panic!("parse authored lexicon JSON {}: {e}", path.display())); if lexicon.pointer("/defs/main/type").and_then(Value::as_str) != Some("record") { continue; } let id = lexicon .get("id") .and_then(Value::as_str) .unwrap_or_else(|| panic!("record lexicon {} has no string id", path.display())); if id.starts_with("space.polymodel.") { collections.push(id.to_owned()); } } collections.sort(); let out_dir = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR set by Cargo")); let out_path = out_dir.join("polymodel_record_collections.rs"); let mut out = File::create(&out_path) .unwrap_or_else(|e| panic!("create generated collections {}: {e}", out_path.display())); writeln!(out, "// Generated by build.rs from authored lexicons where defs.main.type == \"record\".\n// Do not edit.\npub const INDEXED_COLLECTIONS: &[&str] = &[").expect("write generated collections header"); for collection in collections { writeln!(out, " {collection:?},").expect("write generated collection"); } writeln!(out, "];").expect("write generated collections footer");}fn collect_json_paths(dir: &Path, paths: &mut Vec<PathBuf>) { let entries = fs::read_dir(dir).unwrap_or_else(|e| panic!("read lexicon dir {}: {e}", dir.display())); for entry in entries { let entry = entry.unwrap_or_else(|e| panic!("read lexicon dir entry in {}: {e}", dir.display())); let path = entry.path(); if path.is_dir() { collect_json_paths(&path, paths); } else if path.extension().and_then(|ext| ext.to_str()) == Some("json") { paths.push(path); } }}