diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-05-27 20:43:25 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-27 20:43:25 +0200 |
| commit | e8dd585dd8c81fbc5cab31a10d67adba91593d8d (patch) | |
| tree | 3aefe51c881b7800e8cd491535a6f1f51132c25c | |
| parent | 8bd15878eba2905b9c4919f62a340b668c0b31de (diff) | |
| parent | bdf3864d51f7141d9e0fd14c754c7c3b5650af60 (diff) | |
| download | rust-e8dd585dd8c81fbc5cab31a10d67adba91593d8d.tar.gz rust-e8dd585dd8c81fbc5cab31a10d67adba91593d8d.zip | |
Rollup merge of #125542 - GuillaumeGomez:migrate-rustdoc-verify-output-files, r=jieyouxu
Migrate rustdoc verify output files Part of https://github.com/rust-lang/rust/issues/121876. r? ```@jieyouxu```
| -rw-r--r-- | src/tools/run-make-support/src/diff/mod.rs | 5 | ||||
| -rw-r--r-- | src/tools/run-make-support/src/lib.rs | 67 | ||||
| -rw-r--r-- | src/tools/run-make-support/src/rustdoc.rs | 7 | ||||
| -rw-r--r-- | src/tools/tidy/src/allowed_run_make_makefiles.txt | 1 | ||||
| -rw-r--r-- | tests/run-make/rustdoc-verify-output-files/Makefile | 32 | ||||
| -rw-r--r-- | tests/run-make/rustdoc-verify-output-files/rmake.rs | 49 |
6 files changed, 127 insertions, 34 deletions
diff --git a/src/tools/run-make-support/src/diff/mod.rs b/src/tools/run-make-support/src/diff/mod.rs index 332126939c0..d864ddf4eb1 100644 --- a/src/tools/run-make-support/src/diff/mod.rs +++ b/src/tools/run-make-support/src/diff/mod.rs @@ -51,7 +51,10 @@ impl Diff { /// Specify the actual output for the diff from a file. pub fn actual_file<P: AsRef<Path>>(&mut self, path: P) -> &mut Self { let path = path.as_ref(); - let content = std::fs::read_to_string(path).expect("failed to read file"); + let content = match std::fs::read_to_string(path) { + Ok(c) => c, + Err(e) => panic!("failed to read `{}`: {:?}", path.display(), e), + }; let name = path.to_string_lossy().to_string(); self.actual = Some(content); diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 9854d91e19e..d96c8b89127 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -12,6 +12,8 @@ pub mod rustc; pub mod rustdoc; use std::env; +use std::fs; +use std::io; use std::path::{Path, PathBuf}; use std::process::{Command, Output}; @@ -201,6 +203,71 @@ pub fn set_host_rpath(cmd: &mut Command) { }); } +/// Copy a directory into another. +pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) { + fn copy_dir_all_inner(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> { + let dst = dst.as_ref(); + if !dst.is_dir() { + fs::create_dir_all(&dst)?; + } + for entry in fs::read_dir(src)? { + let entry = entry?; + let ty = entry.file_type()?; + if ty.is_dir() { + copy_dir_all_inner(entry.path(), dst.join(entry.file_name()))?; + } else { + fs::copy(entry.path(), dst.join(entry.file_name()))?; + } + } + Ok(()) + } + + if let Err(e) = copy_dir_all_inner(&src, &dst) { + // Trying to give more context about what exactly caused the failure + panic!( + "failed to copy `{}` to `{}`: {:?}", + src.as_ref().display(), + dst.as_ref().display(), + e + ); + } +} + +/// Check that all files in `dir1` exist and have the same content in `dir2`. Panic otherwise. +pub fn recursive_diff(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) { + fn read_file(path: &Path) -> Vec<u8> { + match fs::read(path) { + Ok(c) => c, + Err(e) => panic!("Failed to read `{}`: {:?}", path.display(), e), + } + } + + let dir2 = dir2.as_ref(); + for entry in fs::read_dir(dir1).unwrap() { + let entry = entry.unwrap(); + let entry_name = entry.file_name(); + let path = entry.path(); + + if path.is_dir() { + recursive_diff(&path, &dir2.join(entry_name)); + } else { + let path2 = dir2.join(entry_name); + let file1 = read_file(&path); + let file2 = read_file(&path2); + + // We don't use `assert_eq!` because they are `Vec<u8>`, so not great for display. + // Why not using String? Because there might be minified files or even potentially + // binary ones, so that would display useless output. + assert!( + file1 == file2, + "`{}` and `{}` have different content", + path.display(), + path2.display(), + ); + } + } +} + /// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct /// containing a `cmd: Command` field and a `output` function. The provided helpers are: /// diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs index c4f4e9f9bd2..9c77f1ca462 100644 --- a/src/tools/run-make-support/src/rustdoc.rs +++ b/src/tools/run-make-support/src/rustdoc.rs @@ -151,6 +151,13 @@ impl Rustdoc { self } + /// Specify the output format. + pub fn output_format(&mut self, format: &str) -> &mut Self { + self.cmd.arg("--output-format"); + self.cmd.arg(format); + self + } + #[track_caller] pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output { let caller_location = std::panic::Location::caller(); diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 55d65fe8987..2329b8b44de 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -226,7 +226,6 @@ run-make/rlib-format-packed-bundled-libs/Makefile run-make/rmeta-preferred/Makefile run-make/rustc-macro-dep-files/Makefile run-make/rustdoc-io-error/Makefile -run-make/rustdoc-verify-output-files/Makefile run-make/sanitizer-cdylib-link/Makefile run-make/sanitizer-dylib-link/Makefile run-make/sanitizer-staticlib-link/Makefile diff --git a/tests/run-make/rustdoc-verify-output-files/Makefile b/tests/run-make/rustdoc-verify-output-files/Makefile deleted file mode 100644 index 76f233ab445..00000000000 --- a/tests/run-make/rustdoc-verify-output-files/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -include ../tools.mk - -OUTPUT_DIR := "$(TMPDIR)/rustdoc" -TMP_OUTPUT_DIR := "$(TMPDIR)/tmp-rustdoc" - -all: - # Generate html docs - $(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --out-dir $(OUTPUT_DIR) - - # Copy first output for to check if it's exactly same after second compilation - cp -R $(OUTPUT_DIR) $(TMP_OUTPUT_DIR) - - # Generate html docs once again on same output - $(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --out-dir $(OUTPUT_DIR) - - # Check if everything exactly same - $(DIFF) -r $(OUTPUT_DIR) $(TMP_OUTPUT_DIR) - - # Generate json doc on the same output - $(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --out-dir $(OUTPUT_DIR) -Z unstable-options --output-format json - - # Check if expected json file is generated - [ -e $(OUTPUT_DIR)/foobar.json ] - - # Copy first json output to check if it's exactly same after second compilation - cp -R $(OUTPUT_DIR)/foobar.json $(TMP_OUTPUT_DIR)/foobar.json - - # Generate json doc on the same output - $(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --out-dir $(OUTPUT_DIR) -Z unstable-options --output-format json - - # Check if all docs(including both json and html formats) are still the same after multiple compilations - $(DIFF) -r $(OUTPUT_DIR) $(TMP_OUTPUT_DIR) diff --git a/tests/run-make/rustdoc-verify-output-files/rmake.rs b/tests/run-make/rustdoc-verify-output-files/rmake.rs new file mode 100644 index 00000000000..212e7eaba2d --- /dev/null +++ b/tests/run-make/rustdoc-verify-output-files/rmake.rs @@ -0,0 +1,49 @@ +use std::fs::copy; +use std::path::{Path, PathBuf}; + +use run_make_support::{copy_dir_all, recursive_diff, rustdoc, tmp_dir}; + +#[derive(PartialEq)] +enum JsonOutput { + Yes, + No, +} + +fn generate_docs(out_dir: &Path, json_output: JsonOutput) { + let mut rustdoc = rustdoc(); + rustdoc.input("src/lib.rs").crate_name("foobar").crate_type("lib").out_dir(&out_dir); + if json_output == JsonOutput::Yes { + rustdoc.arg("-Zunstable-options").output_format("json"); + } + rustdoc.run(); +} + +fn main() { + let out_dir = tmp_dir().join("rustdoc"); + let tmp_out_dir = tmp_dir().join("tmp-rustdoc"); + + // Generate HTML docs. + generate_docs(&out_dir, JsonOutput::No); + + // Copy first output for to check if it's exactly same after second compilation. + copy_dir_all(&out_dir, &tmp_out_dir); + + // Generate html docs once again on same output. + generate_docs(&out_dir, JsonOutput::No); + + // Generate json doc on the same output. + generate_docs(&out_dir, JsonOutput::Yes); + + // Check if expected json file is generated. + assert!(out_dir.join("foobar.json").is_file()); + + // Copy first json output to check if it's exactly same after second compilation. + copy(out_dir.join("foobar.json"), tmp_out_dir.join("foobar.json")).unwrap(); + + // Generate json doc on the same output. + generate_docs(&out_dir, JsonOutput::Yes); + + // Check if all docs(including both json and html formats) are still the same after multiple + // compilations. + recursive_diff(&out_dir, &tmp_out_dir); +} |
