From 86abb5439ab71f7aa7cf6c48a84b5bfdd06ba009 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 19 Oct 2024 15:27:53 -0700 Subject: [PATCH] rustdoc: hash assets at rustdoc build time Since sha256 is slow enough to show up on small benchmarks, we can save time by embedding the hash in the executable. --- src/librustdoc/Cargo.toml | 5 ++- src/librustdoc/build.rs | 48 +++++++++++++++++++++++++++++ src/librustdoc/html/static_files.rs | 19 ++++-------- 3 files changed, 58 insertions(+), 14 deletions(-) create mode 100644 src/librustdoc/build.rs diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 42df0b283817b..57b6de67ee8a9 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -2,6 +2,7 @@ name = "rustdoc" version = "0.0.0" edition = "2021" +build = "build.rs" [lib] path = "lib.rs" @@ -24,13 +25,15 @@ tracing = "0.1" tracing-tree = "0.3.0" threadpool = "1.8.1" unicode-segmentation = "1.9" -sha2 = "0.10.8" [dependencies.tracing-subscriber] version = "0.3.3" default-features = false features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] +[build-dependencies] +sha2 = "0.10.8" + [dev-dependencies] expect-test = "1.4.0" diff --git a/src/librustdoc/build.rs b/src/librustdoc/build.rs new file mode 100644 index 0000000000000..69337fb1d2504 --- /dev/null +++ b/src/librustdoc/build.rs @@ -0,0 +1,48 @@ +fn main() { + // generate sha256 files + // this avoids having to perform hashing at runtime + let files = &[ + "static/css/rustdoc.css", + "static/css/noscript.css", + "static/css/normalize.css", + "static/js/main.js", + "static/js/search.js", + "static/js/settings.js", + "static/js/src-script.js", + "static/js/storage.js", + "static/js/scrape-examples.js", + "static/COPYRIGHT.txt", + "static/LICENSE-APACHE.txt", + "static/LICENSE-MIT.txt", + "static/images/rust-logo.svg", + "static/images/favicon.svg", + "static/images/favicon-32x32.png", + "static/fonts/FiraSans-Regular.woff2", + "static/fonts/FiraSans-Medium.woff2", + "static/fonts/FiraSans-LICENSE.txt", + "static/fonts/SourceSerif4-Regular.ttf.woff2", + "static/fonts/SourceSerif4-Bold.ttf.woff2", + "static/fonts/SourceSerif4-It.ttf.woff2", + "static/fonts/SourceSerif4-LICENSE.md", + "static/fonts/SourceCodePro-Regular.ttf.woff2", + "static/fonts/SourceCodePro-Semibold.ttf.woff2", + "static/fonts/SourceCodePro-It.ttf.woff2", + "static/fonts/SourceCodePro-LICENSE.txt", + "static/fonts/NanumBarunGothic.ttf.woff2", + "static/fonts/NanumBarunGothic-LICENSE.txt", + ]; + let out_dir = std::env::var("OUT_DIR").expect("standard Cargo environment variable"); + for path in files { + let inpath = format!("html/{path}"); + println!("cargo::rerun-if-changed={inpath}"); + let bytes = std::fs::read(inpath).expect("static path exists"); + use sha2::Digest; + let bytes = sha2::Sha256::digest(bytes); + let mut digest = format!("-{bytes:x}"); + digest.truncate(9); + let outpath = std::path::PathBuf::from(format!("{out_dir}/{path}.sha256")); + std::fs::create_dir_all(outpath.parent().expect("all file paths are in a directory")) + .expect("should be able to write to out_dir"); + std::fs::write(&outpath, digest.as_bytes()).expect("write to out_dir"); + } +} diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index 9e0803f5d3fd1..a4dc8cd1ed912 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -12,8 +12,8 @@ pub(crate) struct StaticFile { } impl StaticFile { - fn new(filename: &str, bytes: &'static [u8]) -> StaticFile { - Self { filename: static_filename(filename, bytes), bytes } + fn new(filename: &str, bytes: &'static [u8], sha256: &'static str) -> StaticFile { + Self { filename: static_filename(filename, sha256), bytes } } pub(crate) fn minified(&self) -> Vec { @@ -55,17 +55,9 @@ pub(crate) fn suffix_path(filename: &str, suffix: &str) -> PathBuf { filename.into() } -pub(crate) fn static_filename(filename: &str, contents: &[u8]) -> PathBuf { +pub(crate) fn static_filename(filename: &str, sha256: &str) -> PathBuf { let filename = filename.rsplit('/').next().unwrap(); - suffix_path(filename, &static_suffix(contents)) -} - -fn static_suffix(bytes: &[u8]) -> String { - use sha2::Digest; - let bytes = sha2::Sha256::digest(bytes); - let mut digest = format!("-{bytes:x}"); - digest.truncate(9); - digest + suffix_path(filename, &sha256) } macro_rules! static_files { @@ -74,8 +66,9 @@ macro_rules! static_files { $(pub $field: StaticFile,)+ } + // sha256 files are generated in build.rs pub(crate) static STATIC_FILES: std::sync::LazyLock = std::sync::LazyLock::new(|| StaticFiles { - $($field: StaticFile::new($file_path, include_bytes!($file_path)),)+ + $($field: StaticFile::new($file_path, include_bytes!($file_path), include_str!(concat!(env!("OUT_DIR"), "/", $file_path, ".sha256"))),)+ }); pub(crate) fn for_each(f: impl Fn(&StaticFile) -> Result<(), E>) -> Result<(), E> {