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.
This commit is contained in:
parent
8069f8d17a
commit
86abb5439a
@ -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