Files
Mateusz Gruszczyński a643e7e3ab
RustBox CI / rustbox (push) Waiting to run
v0.0.5
2026-10-30 12:06:44 +01:00

80 lines
2.6 KiB
Rust

use std::{
env, fs,
path::{Path, PathBuf},
};
fn fnv1a64(parts: &[&[u8]]) -> u64 {
let mut hash = 0xcbf29ce484222325u64;
for part in parts {
for byte in *part {
hash ^= u64::from(*byte);
hash = hash.wrapping_mul(0x100000001b3);
}
}
hash
}
fn bundle_manifest(root: &Path, directory: &Path, manifest: &Path, extension: &str) -> String {
println!("cargo:rerun-if-changed={}", manifest.display());
let manifest_text = fs::read_to_string(manifest)
.unwrap_or_else(|error| panic!("{}: {error}", manifest.display()));
let mut bundle = String::new();
for raw in manifest_text.lines() {
let name = raw.trim();
if name.is_empty() || name.starts_with('#') {
continue;
}
assert!(
name.ends_with(extension)
&& !name.contains('/')
&& !name.contains('\\')
&& !name.contains(".."),
"invalid {extension} manifest entry: {name}"
);
let path = directory.join(name);
assert!(
path.starts_with(root),
"asset path escaped project root: {}",
path.display()
);
println!("cargo:rerun-if-changed={}", path.display());
let source =
fs::read_to_string(&path).unwrap_or_else(|error| panic!("{}: {error}", path.display()));
if !bundle.is_empty() {
bundle.push('\n');
}
bundle.push_str(&source);
if !source.ends_with('\n') {
bundle.push('\n');
}
}
bundle
}
fn main() {
let root = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR"));
let out = PathBuf::from(env::var_os("OUT_DIR").expect("OUT_DIR"));
let css_dir = root.join("src/web/css");
let js_dir = root.join("src/web/js");
for path in [
root.join("src/web/index.html"),
root.join("src/web/icons.svg"),
root.join("src/web/i18n/en.json"),
root.join("src/web/i18n/pl.json"),
] {
println!("cargo:rerun-if-changed={}", path.display());
}
let css_bundle = bundle_manifest(&root, &css_dir, &css_dir.join("manifest.txt"), ".css");
let js_bundle = bundle_manifest(&root, &js_dir, &js_dir.join("manifest.txt"), ".js");
let asset_id = fnv1a64(&[css_bundle.as_bytes(), js_bundle.as_bytes()]);
println!("cargo:rustc-env=RUSTBOX_ASSET_ID={asset_id:016x}");
fs::write(out.join("rustbox-ui.css"), css_bundle).expect("write RustBox CSS bundle");
fs::write(out.join("rustbox-ui.js"), js_bundle).expect("write RustBox JavaScript bundle");
}