about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Howell <michael@notriddle.com>2024-10-19 15:27:53 -0700
committerMichael Howell <michael@notriddle.com>2024-10-19 15:36:19 -0700
commit86abb5439ab71f7aa7cf6c48a84b5bfdd06ba009 (patch)
treeba5b3500a0112e581dc7fa1abd567998c3875775
parent8069f8d17a6c86a8fd881939fcce359a90c57ff2 (diff)
downloadrust-86abb5439ab71f7aa7cf6c48a84b5bfdd06ba009.tar.gz
rust-86abb5439ab71f7aa7cf6c48a84b5bfdd06ba009.zip
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.
-rw-r--r--src/librustdoc/Cargo.toml5
-rw-r--r--src/librustdoc/build.rs48
-rw-r--r--src/librustdoc/html/static_files.rs19
3 files changed, 58 insertions, 14 deletions
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index 42df0b28381..57b6de67ee8 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 00000000000..69337fb1d25
--- /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 9e0803f5d3f..a4dc8cd1ed9 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<u8> {
@@ -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<StaticFiles> = 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<E>(f: impl Fn(&StaticFile) -> Result<(), E>) -> Result<(), E> {