parallelize tidy checks

This commit is contained in:
The8472 2021-02-20 22:45:30 +01:00
parent 5233edcf1c
commit 77d1185f00
5 changed files with 67 additions and 30 deletions

View File

@ -5239,6 +5239,7 @@ name = "tidy"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"cargo_metadata 0.11.1", "cargo_metadata 0.11.1",
"crossbeam-utils 0.8.0",
"lazy_static", "lazy_static",
"regex", "regex",
"walkdir", "walkdir",

View File

@ -10,6 +10,7 @@ cargo_metadata = "0.11"
regex = "1" regex = "1"
lazy_static = "1" lazy_static = "1"
walkdir = "2" walkdir = "2"
crossbeam-utils = "0.8.0"
[[bin]] [[bin]]
name = "rust-tidy" name = "rust-tidy"

View File

@ -32,9 +32,12 @@ fn is_executable(path: &Path) -> std::io::Result<bool> {
// readily create a file there to test. // readily create a file there to test.
// //
// See #36706 and #74753 for context. // See #36706 and #74753 for context.
let mut temp_path = path.join("tidy-test-file"); //
// We also add the thread ID to avoid threads trampling on each others files.
let file_name = format!("t{}.tidy-test-file", std::thread::current().id().as_u64());
let mut temp_path = path.join(&file_name);
match fs::File::create(&temp_path).or_else(|_| { match fs::File::create(&temp_path).or_else(|_| {
temp_path = output.join("tidy-test-file"); temp_path = output.join(&file_name);
fs::File::create(&temp_path) fs::File::create(&temp_path)
}) { }) {
Ok(file) => { Ok(file) => {

View File

@ -4,6 +4,7 @@
//! to be used by tools. //! to be used by tools.
#![cfg_attr(bootstrap, feature(str_split_once))] #![cfg_attr(bootstrap, feature(str_split_once))]
#![feature(thread_id_value)]
use std::fs::File; use std::fs::File;
use std::io::Read; use std::io::Read;
@ -54,6 +55,12 @@ macro_rules! tidy_error {
pub mod unstable_book; pub mod unstable_book;
fn filter_dirs(path: &Path) -> bool { fn filter_dirs(path: &Path) -> bool {
// Filter out temporary files used by the bins module to probe the filesystem
match path.extension() {
Some(ext) if ext == "tidy-test-file" => return true,
_ => {}
}
let skip = [ let skip = [
"compiler/rustc_codegen_cranelift", "compiler/rustc_codegen_cranelift",
"src/llvm-project", "src/llvm-project",

View File

@ -6,9 +6,11 @@
use tidy::*; use tidy::*;
use crossbeam_utils::thread::scope;
use std::env; use std::env;
use std::path::PathBuf; use std::path::PathBuf;
use std::process; use std::process;
use std::sync::atomic::{AtomicBool, Ordering};
fn main() { fn main() {
let root_path: PathBuf = env::args_os().nth(1).expect("need path to root of repo").into(); let root_path: PathBuf = env::args_os().nth(1).expect("need path to root of repo").into();
@ -22,45 +24,68 @@ fn main() {
let args: Vec<String> = env::args().skip(1).collect(); let args: Vec<String> = env::args().skip(1).collect();
let mut bad = false;
let verbose = args.iter().any(|s| *s == "--verbose"); let verbose = args.iter().any(|s| *s == "--verbose");
// Checks over tests. let bad = std::sync::Arc::new(AtomicBool::new(false));
debug_artifacts::check(&src_path, &mut bad);
ui_tests::check(&src_path, &mut bad);
// Checks that only make sense for the compiler. scope(|s| {
errors::check(&compiler_path, &mut bad); macro_rules! check {
error_codes_check::check(&src_path, &mut bad); ($p:ident $(, $args:expr)* ) => {
s.spawn(|_| {
let mut flag = false;
$p::check($($args),* , &mut flag);
if (flag) {
bad.store(true, Ordering::Relaxed);
}
});
}
}
// Checks that only make sense for the std libs. // Checks that are done on the cargo workspace.
pal::check(&library_path, &mut bad); check!(deps, &root_path, &cargo);
check!(extdeps, &root_path);
// Checks that need to be done for both the compiler and std libraries. // Checks over tests.
unit_tests::check(&src_path, &mut bad); check!(debug_artifacts, &src_path);
unit_tests::check(&compiler_path, &mut bad); check!(ui_tests, &src_path);
unit_tests::check(&library_path, &mut bad);
bins::check(&src_path, &output_directory, &mut bad); // Checks that only make sense for the compiler.
bins::check(&compiler_path, &output_directory, &mut bad); check!(errors, &compiler_path);
bins::check(&library_path, &output_directory, &mut bad); check!(error_codes_check, &src_path);
style::check(&src_path, &mut bad); // Checks that only make sense for the std libs.
style::check(&compiler_path, &mut bad); check!(pal, &library_path);
style::check(&library_path, &mut bad);
edition::check(&src_path, &mut bad); // Checks that need to be done for both the compiler and std libraries.
edition::check(&compiler_path, &mut bad); check!(unit_tests, &src_path);
edition::check(&library_path, &mut bad); check!(unit_tests, &compiler_path);
check!(unit_tests, &library_path);
let collected = features::check(&src_path, &compiler_path, &library_path, &mut bad, verbose); check!(bins, &src_path, &output_directory);
unstable_book::check(&src_path, collected, &mut bad); check!(bins, &compiler_path, &output_directory);
check!(bins, &library_path, &output_directory);
// Checks that are done on the cargo workspace. check!(style, &src_path);
deps::check(&root_path, &cargo, &mut bad); check!(style, &compiler_path);
extdeps::check(&root_path, &mut bad); check!(style, &library_path);
if bad { check!(edition, &src_path);
check!(edition, &compiler_path);
check!(edition, &library_path);
let collected = {
let mut flag = false;
let r = features::check(&src_path, &compiler_path, &library_path, &mut flag, verbose);
if flag {
bad.store(true, Ordering::Relaxed);
}
r
};
check!(unstable_book, &src_path, collected);
})
.unwrap();
if bad.load(Ordering::Relaxed) {
eprintln!("some tidy checks failed"); eprintln!("some tidy checks failed");
process::exit(1); process::exit(1);
} }