Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate rustdoc verify output files #125542

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/tools/run-make-support/src/diff/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
67 changes: 67 additions & 0 deletions src/tools/run-make-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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:
///
Expand Down
7 changes: 7 additions & 0 deletions src/tools/run-make-support/src/rustdoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
1 change: 0 additions & 1 deletion src/tools/tidy/src/allowed_run_make_makefiles.txt
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,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
Expand Down
32 changes: 0 additions & 32 deletions tests/run-make/rustdoc-verify-output-files/Makefile

This file was deleted.

49 changes: 49 additions & 0 deletions tests/run-make/rustdoc-verify-output-files/rmake.rs
Original file line number Diff line number Diff line change
@@ -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);
}
Loading