Skip to content

Commit

Permalink
rustdoc: hash assets at rustdoc build time
Browse files Browse the repository at this point in the history
Since sha256 is slow enough to show up on small benchmarks,
we can save time by embedding the hash in the executable.
  • Loading branch information
notriddle committed Oct 19, 2024
1 parent 8069f8d commit 86abb54
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 14 deletions.
5 changes: 4 additions & 1 deletion src/librustdoc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "rustdoc"
version = "0.0.0"
edition = "2021"
build = "build.rs"

[lib]
path = "lib.rs"
Expand All @@ -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"

Expand Down
48 changes: 48 additions & 0 deletions src/librustdoc/build.rs
Original file line number Diff line number Diff line change
@@ -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");
}
}
19 changes: 6 additions & 13 deletions src/librustdoc/html/static_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -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 {
Expand All @@ -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> {
Expand Down

0 comments on commit 86abb54

Please sign in to comment.