Auto merge of #131951 - notriddle:notriddle/sha256-compile-time, r=GuillaumeGomez
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. Addresses https://github.com/rust-lang/rust/pull/131934#issuecomment-2424213861
This commit is contained in:
commit
8aca4bab08
@ -2,6 +2,7 @@
|
|||||||
name = "rustdoc"
|
name = "rustdoc"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
path = "lib.rs"
|
path = "lib.rs"
|
||||||
@ -24,13 +25,15 @@ tracing = "0.1"
|
|||||||
tracing-tree = "0.3.0"
|
tracing-tree = "0.3.0"
|
||||||
threadpool = "1.8.1"
|
threadpool = "1.8.1"
|
||||||
unicode-segmentation = "1.9"
|
unicode-segmentation = "1.9"
|
||||||
sha2 = "0.10.8"
|
|
||||||
|
|
||||||
[dependencies.tracing-subscriber]
|
[dependencies.tracing-subscriber]
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"]
|
features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"]
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
sha2 = "0.10.8"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
expect-test = "1.4.0"
|
expect-test = "1.4.0"
|
||||||
|
|
||||||
|
48
src/librustdoc/build.rs
Normal file
48
src/librustdoc/build.rs
Normal file
@ -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");
|
||||||
|
}
|
||||||
|
}
|
@ -12,8 +12,8 @@ pub(crate) struct StaticFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl StaticFile {
|
impl StaticFile {
|
||||||
fn new(filename: &str, bytes: &'static [u8]) -> StaticFile {
|
fn new(filename: &str, bytes: &'static [u8], sha256: &'static str) -> StaticFile {
|
||||||
Self { filename: static_filename(filename, bytes), bytes }
|
Self { filename: static_filename(filename, sha256), bytes }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn minified(&self) -> Vec<u8> {
|
pub(crate) fn minified(&self) -> Vec<u8> {
|
||||||
@ -55,17 +55,9 @@ pub(crate) fn suffix_path(filename: &str, suffix: &str) -> PathBuf {
|
|||||||
filename.into()
|
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();
|
let filename = filename.rsplit('/').next().unwrap();
|
||||||
suffix_path(filename, &static_suffix(contents))
|
suffix_path(filename, &sha256)
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! static_files {
|
macro_rules! static_files {
|
||||||
@ -74,8 +66,9 @@ pub(crate) struct StaticFiles {
|
|||||||
$(pub $field: StaticFile,)+
|
$(pub $field: StaticFile,)+
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sha256 files are generated in build.rs
|
||||||
pub(crate) static STATIC_FILES: std::sync::LazyLock<StaticFiles> = std::sync::LazyLock::new(|| StaticFiles {
|
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> {
|
pub(crate) fn for_each<E>(f: impl Fn(&StaticFile) -> Result<(), E>) -> Result<(), E> {
|
||||||
|
Loading…
Reference in New Issue
Block a user