use std::{fs, path::PathBuf, ffi::OsStr, process::Command, error::Error}; use css_minify::optimizations::{Minifier, Level}; fn asset_path(asset: &PathBuf) -> PathBuf { let mut path = asset.components().take(1).collect::(); path.push(asset.components().last().unwrap()); path } fn template_path(template: &PathBuf) -> PathBuf { let mut path = template.components().take(template.components().count() - 2).collect::(); path.push(template.components().last().unwrap()); path } fn extfilter(valid: String, x: Option<&OsStr>) -> bool { if x.is_none() { return false } let ext = x.clone().unwrap().to_str().unwrap().to_string(); ext == valid } fn system(cmd: &str, args: &[&str]) -> Result> { let out = Command::new(cmd) .args(args) .output() ?; if out.stderr.len() != 0 { panic!("Got this while running {cmd} with \"{}\": {}", args.join(" "), String::from_utf8(out.stderr).unwrap()) } Ok(String::from_utf8(out.stdout)?) } fn main() { println!("cargo:rerun-if-changed=static/assets"); println!("cargo:rerun-if-changed=templates/source"); let assets = fs::read_dir("static/assets").unwrap(); let assets = assets .map(|x| x.unwrap().path()) .filter(|x| x.extension().is_some()) .collect::>(); let styles = assets .iter() .filter(|x| { extfilter("css".into(), x.extension()) }) .collect::>(); let scripts = assets .iter() .filter(|x| { extfilter("js".into(), x.extension()) }) .collect::>(); styles.iter().for_each(|asset| { let bundled = Minifier::default().minify( String::from_utf8(fs::read(asset).unwrap()).unwrap().as_str(), Level::Zero ).unwrap(); fs::write(asset_path(asset), bundled).unwrap(); }); scripts.iter().for_each(|asset| { Command::new("uglifyjs") .arg(asset) .arg("-o") .arg(asset_path(asset)) .arg("-c") .spawn() .unwrap(); }); // precompile templates let templates = fs::read_dir("templates/source").unwrap(); let templates = templates .map(|x| x.unwrap().path().canonicalize().unwrap()) .filter(|x| extfilter("html".into(), x.extension())) .collect::>(); templates.iter().for_each(|template| { Command::new("html-minifier") .arg(template.canonicalize().unwrap()) .arg("--collapse-whitespace") // .arg("--minify-js") // .arg("--minify-css") // .arg("--keep-closing-slash") .arg("--output") .arg(template_path(template)) .spawn() .unwrap(); }); let commit = system("git", &["rev-parse", "HEAD"]).map_err(|x| x.to_string()); let branch = system("git", &["rev-parse", "--abbrev-ref", "HEAD"]).map_err(|x| x.to_string()); match commit { Err(err) => panic!("Can't get commit: {}", err), Ok(commit) => println!("cargo:rustc-env=COMMIT_HASH={commit}") } match branch { Err(err) => panic!("Can't get commit: {}", err), Ok(branch) => println!("cargo:rustc-env=COMMIT_BRANCH={branch}") } }