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

Rollup of 2 pull requests #125621

Closed
Closed
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 @@ -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
Expand Down
8 changes: 4 additions & 4 deletions src/tools/tidy/src/ui_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ use std::path::{Path, PathBuf};
// should all be 1000 or lower. Limits significantly smaller than 1000 are also
// desirable, because large numbers of files are unwieldy in general. See issue
// #73494.
const ENTRY_LIMIT: usize = 900;
const ENTRY_LIMIT: u32 = 900;
// FIXME: The following limits should be reduced eventually.

const ISSUES_ENTRY_LIMIT: usize = 1676;
const ISSUES_ENTRY_LIMIT: u32 = 1676;

const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
"rs", // test source files
Expand Down Expand Up @@ -53,7 +53,7 @@ const EXTENSION_EXCEPTION_PATHS: &[&str] = &[
];

fn check_entries(tests_path: &Path, bad: &mut bool) {
let mut directories: HashMap<PathBuf, usize> = HashMap::new();
let mut directories: HashMap<PathBuf, u32> = HashMap::new();

for dir in Walk::new(&tests_path.join("ui")) {
if let Ok(entry) = dir {
Expand All @@ -62,7 +62,7 @@ fn check_entries(tests_path: &Path, bad: &mut bool) {
}
}

let (mut max, mut max_issues) = (0usize, 0usize);
let (mut max, mut max_issues) = (0, 0);
for (dir_path, count) in directories {
let is_issues_dir = tests_path.join("ui/issues") == dir_path;
let (limit, maxcnt) = if is_issues_dir {
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