rustdoc: fix a few spots where emit isn't respected

This commit is contained in:
Michael Howell
2026-04-15 20:27:12 -07:00
parent 2f201bccb3
commit de48fc6a56
4 changed files with 77 additions and 35 deletions
+27 -25
View File
@@ -153,7 +153,7 @@ pub(crate) fn write_not_crate_specific(
include_sources: bool,
) -> Result<(), Error> {
write_rendered_cross_crate_info(crates, dst, opt, include_sources, resource_suffix)?;
write_static_files(dst, opt, style_files, css_file_extension, resource_suffix)?;
write_resources(dst, opt, style_files, css_file_extension, resource_suffix)?;
Ok(())
}
@@ -183,43 +183,45 @@ fn write_rendered_cross_crate_info(
/// Writes the static files, the style files, and the css extensions.
/// Have to be careful about these, because they write to the root out dir.
fn write_static_files(
fn write_resources(
dst: &Path,
opt: &RenderOptions,
style_files: &[StylePath],
css_file_extension: Option<&Path>,
resource_suffix: &str,
) -> Result<(), Error> {
let static_dir = dst.join("static.files");
try_err!(fs::create_dir_all(&static_dir), &static_dir);
if opt.emit.is_empty() || opt.emit.contains(&EmitType::HtmlNonStaticFiles) {
// Handle added third-party themes
for entry in style_files {
let theme = entry.basename()?;
let extension =
try_none!(try_none!(entry.path.extension(), &entry.path).to_str(), &entry.path);
// Handle added third-party themes
for entry in style_files {
let theme = entry.basename()?;
let extension =
try_none!(try_none!(entry.path.extension(), &entry.path).to_str(), &entry.path);
// Skip the official themes. They are written below as part of STATIC_FILES_LIST.
if matches!(theme.as_str(), "light" | "dark" | "ayu") {
continue;
}
// Skip the official themes. They are written below as part of STATIC_FILES_LIST.
if matches!(theme.as_str(), "light" | "dark" | "ayu") {
continue;
let bytes = try_err!(fs::read(&entry.path), &entry.path);
let filename = format!("{theme}{resource_suffix}.{extension}");
let dst_filename = dst.join(filename);
try_err!(fs::write(&dst_filename, bytes), &dst_filename);
}
let bytes = try_err!(fs::read(&entry.path), &entry.path);
let filename = format!("{theme}{resource_suffix}.{extension}");
let dst_filename = dst.join(filename);
try_err!(fs::write(&dst_filename, bytes), &dst_filename);
}
// When the user adds their own CSS files with --extend-css, we write that as an
// invocation-specific file (that is, with a resource suffix).
if let Some(css) = css_file_extension {
let buffer = try_err!(fs::read_to_string(css), css);
let path = static_files::suffix_path("theme.css", resource_suffix);
let dst_path = dst.join(path);
try_err!(fs::write(&dst_path, buffer), &dst_path);
// When the user adds their own CSS files with --extend-css, we write that as an
// invocation-specific file (that is, with a resource suffix).
if let Some(css) = css_file_extension {
let buffer = try_err!(fs::read_to_string(css), css);
let path = static_files::suffix_path("theme.css", resource_suffix);
let dst_path = dst.join(path);
try_err!(fs::write(&dst_path, buffer), &dst_path);
}
}
if opt.emit.is_empty() || opt.emit.contains(&EmitType::HtmlStaticFiles) {
let static_dir = dst.join("static.files");
try_err!(fs::create_dir_all(&static_dir), &static_dir);
static_files::for_each(|f: &static_files::StaticFile| {
let filename = static_dir.join(f.output_filename());
let contents: &[u8] =
+6 -1
View File
@@ -81,6 +81,7 @@
use tracing::info;
use crate::clean::utils::DOC_RUST_LANG_ORG_VERSION;
use crate::config::EmitType;
use crate::error::Error;
use crate::formats::cache::Cache;
@@ -868,7 +869,11 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) {
};
rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| {
let has_dep_info = render_options.dep_info().is_some();
markdown::render_and_write(file, render_options, edition)?;
if render_options.emit.contains(&EmitType::HtmlNonStaticFiles)
|| render_options.emit.is_empty()
{
markdown::render_and_write(file, render_options, edition)?;
}
if has_dep_info {
// Register the loaded external files in the source map so they show up in depinfo.
// We can't load them via the source map because it gets created after we process the options.
+44 -9
View File
@@ -9,8 +9,6 @@
fn main() {
rfs::create_dir("doc");
// We're only emitting dep info, so we shouldn't be running static analysis to
// figure out that this program is erroneous.
// Ensure that all kinds of input reading flags end up in dep-info.
rustdoc()
.input("lib.rs")
@@ -18,7 +16,7 @@ fn main() {
.arg("--html-before-content=before.html")
.arg("--markdown-after-content=after.md")
.arg("--extend-css=extend.css")
.arg("--theme=theme.css")
.arg("--theme=custom_theme.css")
.arg("--index-page=index-page.md")
.emit("dep-info")
.run();
@@ -31,8 +29,31 @@ fn main() {
assert_contains(&content, "after.md:");
assert_contains(&content, "before.html:");
assert_contains(&content, "extend.css:");
assert_contains(&content, "theme.css:");
assert_contains(&content, "custom_theme.css:");
assert_contains(&content, "index-page.md:");
// Only emit dep-info. Don't emit the actual page.
assert!(!path("doc/foo/index.html").exists());
assert!(!path("doc/custom_theme.css").exists());
// weird that --extend-css generates a file named theme.css
assert!(!path("doc/theme.css").exists());
// Now try emitting dep-info and html files at the same time.
rustdoc()
.input("lib.rs")
.arg("-Zunstable-options")
.arg("--html-before-content=before.html")
.arg("--markdown-after-content=after.md")
.arg("--extend-css=extend.css")
.arg("--theme=custom_theme.css")
.arg("--index-page=index-page.md")
.emit("dep-info,html-non-static-files,html-static-files")
.run();
assert!(path("doc/foo/index.html").exists());
// These files are copied into the doc output folder,
// which is why they show up in dep-info.
assert!(path("doc/custom_theme.css").exists());
// weird that --extend-css generates a file named theme.css
assert!(path("doc/theme.css").exists());
// Now we check that we can provide a file name to the `dep-info` argument.
rustdoc().input("lib.rs").arg("-Zunstable-options").emit("dep-info=bla.d").run();
@@ -72,7 +93,9 @@ fn main() {
assert_not_contains(&content, "after.md:");
assert_not_contains(&content, "before.html:");
assert_not_contains(&content, "extend.css:");
assert_not_contains(&content, "theme.css:");
assert_not_contains(&content, "custom_theme.css:");
// Only emit dep-info, not the actual html.
assert!(!path("doc/example.html").exists());
// combine --emit=dep-info=filename with plain markdown input
rustdoc()
@@ -81,10 +104,12 @@ fn main() {
.arg("--html-before-content=before.html")
.arg("--markdown-after-content=after.md")
.arg("--extend-css=extend.css")
.arg("--theme=theme.css")
.arg("--theme=custom_theme.css")
.arg("--markdown-css=markdown.css")
.arg("--index-page=index-page.md")
.emit("dep-info=example.d")
.emit("dep-info=example.d,html-non-static-files,html-static-files")
.run();
assert!(path("doc/example.html").exists());
let content = rfs::read_to_string("example.d");
assert_contains(&content, "example.md:");
assert_not_contains(&content, "lib.rs:");
@@ -93,7 +118,17 @@ fn main() {
assert_not_contains(&content, "doc.md:");
assert_contains(&content, "after.md:");
assert_contains(&content, "before.html:");
assert_contains(&content, "extend.css:");
assert_contains(&content, "theme.css:");
assert_contains(&content, "index-page.md:");
// This is a hotlink, not a file that gets copied,
// so it shouldn't add to the dep-info, it shouldn't be copied,
// and it shouldn't be resolved relative to the root path.
//
// It's weird that this is different from the other two css
// files, but it's stable, so I can't change it.
assert!(!path("doc/markdown.css").exists());
assert_not_contains(&content, "markdown.css:");
// These files aren't actually used, and the fact that they show up
// is arguably a bug, but test it anyway.
assert_contains(&content, "extend.css:");
assert_contains(&content, "custom_theme.css:");
}