Skip to content

Commit 6710835

Browse files
committed
Auto merge of #146592 - Kobzol:tidy-diag, r=jieyouxu
Implement a simple diagnostic system for tidy In #146316 and #146580, contributors independently wanted to reduce the verbose output of tidy. But before, the output was quite ad-hoc, so it was not easy to control it. In this PR, I implemented a simple diagnostic system for tidy, which allows us to: 1) Only print certain information in verbose mode (`-v`) 2) Associate each (error) output to a specific check, so that it is easier to find out what exactly has failed and which check you might want to examine (not fully done, there are some random `println`s left, but most output should be scoped to a specific check) 3) Print output with colors, based on the message level (message, warning, error) 4) Show the start/end execution of each check in verbose mode, for better progress indication Failure output: <img width="1134" height="157" alt="image" src="https://github.com/user-attachments/assets/578a9302-e1c2-47e5-9370-a3556c49d9fc" /> Success output: <img width="388" height="113" alt="image" src="https://github.com/user-attachments/assets/cf27faf8-3d8b-49e3-88d0-fac27a9c36a8" /> Verbose output (shortened): <img width="380" height="158" alt="image" src="https://github.com/user-attachments/assets/ce7102b8-c2f3-42a8-a2ec-ca30389be91e" /> CC `@nnethercote` `@RalfJung` `@GuillaumeGomez` The first two commits and the last commit are interesting, the rest is just mechanical port of the code from `bad: &mut bool` to `DiagCtx` and `RunningCheck`. The `extra_checks` check could be further split, but I'd leave that for another PR. r? `@jieyouxu`
2 parents 1d23da6 + 4c208f5 commit 6710835

39 files changed

+781
-580
lines changed

src/tools/features-status-dump/src/main.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::path::PathBuf;
55

66
use anyhow::{Context, Result};
77
use clap::Parser;
8+
use tidy::diagnostics::RunningCheck;
89
use tidy::features::{Feature, collect_lang_features, collect_lib_features};
910

1011
#[derive(Debug, Parser)]
@@ -29,7 +30,7 @@ struct FeaturesStatus {
2930
fn main() -> Result<()> {
3031
let Cli { compiler_path, library_path, output_path } = Cli::parse();
3132

32-
let lang_features_status = collect_lang_features(&compiler_path, &mut false);
33+
let lang_features_status = collect_lang_features(&compiler_path, &mut RunningCheck::new_noop());
3334
let lib_features_status = collect_lib_features(&library_path)
3435
.into_iter()
3536
.filter(|&(ref name, _)| !lang_features_status.contains_key(name))

src/tools/tidy/src/alphabetical.rs

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use std::fmt::Display;
2424
use std::iter::Peekable;
2525
use std::path::Path;
2626

27+
use crate::diagnostics::{CheckId, DiagCtx, RunningCheck};
2728
use crate::walk::{filter_dirs, walk};
2829

2930
#[cfg(test)]
@@ -43,8 +44,7 @@ const END_MARKER: &str = "tidy-alphabetical-end";
4344
fn check_section<'a>(
4445
file: impl Display,
4546
lines: impl Iterator<Item = (usize, &'a str)>,
46-
err: &mut dyn FnMut(&str) -> std::io::Result<()>,
47-
bad: &mut bool,
47+
check: &mut RunningCheck,
4848
) {
4949
let mut prev_line = String::new();
5050
let mut first_indent = None;
@@ -56,12 +56,10 @@ fn check_section<'a>(
5656
}
5757

5858
if line.contains(START_MARKER) {
59-
tidy_error_ext!(
60-
err,
61-
bad,
59+
check.error(format!(
6260
"{file}:{} found `{START_MARKER}` expecting `{END_MARKER}`",
6361
idx + 1
64-
);
62+
));
6563
return;
6664
}
6765

@@ -104,45 +102,44 @@ fn check_section<'a>(
104102
let prev_line_trimmed_lowercase = prev_line.trim_start_matches(' ');
105103

106104
if version_sort(trimmed_line, prev_line_trimmed_lowercase).is_lt() {
107-
tidy_error_ext!(err, bad, "{file}:{}: line not in alphabetical order", idx + 1);
105+
check.error(format!("{file}:{}: line not in alphabetical order", idx + 1));
108106
}
109107

110108
prev_line = line;
111109
}
112110

113-
tidy_error_ext!(err, bad, "{file}: reached end of file expecting `{END_MARKER}`")
111+
check.error(format!("{file}: reached end of file expecting `{END_MARKER}`"));
114112
}
115113

116114
fn check_lines<'a>(
117115
file: &impl Display,
118116
mut lines: impl Iterator<Item = (usize, &'a str)>,
119-
err: &mut dyn FnMut(&str) -> std::io::Result<()>,
120-
bad: &mut bool,
117+
check: &mut RunningCheck,
121118
) {
122119
while let Some((idx, line)) = lines.next() {
123120
if line.contains(END_MARKER) {
124-
tidy_error_ext!(
125-
err,
126-
bad,
121+
check.error(format!(
127122
"{file}:{} found `{END_MARKER}` expecting `{START_MARKER}`",
128123
idx + 1
129-
)
124+
));
130125
}
131126

132127
if line.contains(START_MARKER) {
133-
check_section(file, &mut lines, err, bad);
128+
check_section(file, &mut lines, check);
134129
}
135130
}
136131
}
137132

138-
pub fn check(path: &Path, bad: &mut bool) {
133+
pub fn check(path: &Path, diag_ctx: DiagCtx) {
134+
let mut check = diag_ctx.start_check(CheckId::new("alphabetical").path(path));
135+
139136
let skip =
140137
|path: &_, _is_dir| filter_dirs(path) || path.ends_with("tidy/src/alphabetical/tests.rs");
141138

142139
walk(path, skip, &mut |entry, contents| {
143140
let file = &entry.path().display();
144141
let lines = contents.lines().enumerate();
145-
check_lines(file, lines, &mut crate::tidy_error, bad)
142+
check_lines(file, lines, &mut check)
146143
});
147144
}
148145

src/tools/tidy/src/alphabetical/tests.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
1-
use std::io::Write;
2-
use std::str::from_utf8;
1+
use std::path::Path;
32

4-
use super::*;
3+
use crate::alphabetical::check_lines;
4+
use crate::diagnostics::DiagCtx;
55

66
#[track_caller]
77
fn test(lines: &str, name: &str, expected_msg: &str, expected_bad: bool) {
8-
let mut actual_msg = Vec::new();
9-
let mut actual_bad = false;
10-
let mut err = |args: &_| {
11-
write!(&mut actual_msg, "{args}")?;
12-
Ok(())
13-
};
14-
check_lines(&name, lines.lines().enumerate(), &mut err, &mut actual_bad);
15-
assert_eq!(expected_msg, from_utf8(&actual_msg).unwrap());
16-
assert_eq!(expected_bad, actual_bad);
8+
let diag_ctx = DiagCtx::new(Path::new("/"), false);
9+
let mut check = diag_ctx.start_check("alphabetical-test");
10+
check_lines(&name, lines.lines().enumerate(), &mut check);
11+
12+
assert_eq!(expected_bad, check.is_bad());
13+
let errors = check.get_errors();
14+
if expected_bad {
15+
assert_eq!(errors.len(), 1);
16+
assert_eq!(expected_msg, errors[0]);
17+
} else {
18+
assert!(errors.is_empty());
19+
}
1720
}
1821

1922
#[track_caller]

src/tools/tidy/src/bins.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ pub use os_impl::*;
1212
mod os_impl {
1313
use std::path::Path;
1414

15+
use crate::diagnostics::DiagCtx;
16+
1517
pub fn check_filesystem_support(_sources: &[&Path], _output: &Path) -> bool {
1618
return false;
1719
}
1820

19-
pub fn check(_path: &Path, _bad: &mut bool) {}
21+
pub fn check(_path: &Path, _diag_ctx: DiagCtx) {}
2022
}
2123

2224
#[cfg(unix)]
@@ -36,6 +38,8 @@ mod os_impl {
3638

3739
use FilesystemSupport::*;
3840

41+
use crate::diagnostics::DiagCtx;
42+
3943
fn is_executable(path: &Path) -> std::io::Result<bool> {
4044
Ok(path.metadata()?.mode() & 0o111 != 0)
4145
}
@@ -106,14 +110,16 @@ mod os_impl {
106110
}
107111

108112
#[cfg(unix)]
109-
pub fn check(path: &Path, bad: &mut bool) {
113+
pub fn check(path: &Path, diag_ctx: DiagCtx) {
114+
let mut check = diag_ctx.start_check("bins");
115+
110116
use std::ffi::OsStr;
111117

112118
const ALLOWED: &[&str] = &["configure", "x"];
113119

114120
for p in RI_EXCLUSION_LIST {
115121
if !path.join(Path::new(p)).exists() {
116-
tidy_error!(bad, "rust-installer test bins missed: {p}");
122+
check.error(format!("rust-installer test bins missed: {p}"));
117123
}
118124
}
119125

@@ -153,7 +159,7 @@ mod os_impl {
153159
});
154160
let path_bytes = rel_path.as_os_str().as_bytes();
155161
if output.status.success() && output.stdout.starts_with(path_bytes) {
156-
tidy_error!(bad, "binary checked into source: {}", file.display());
162+
check.error(format!("binary checked into source: {}", file.display()));
157163
}
158164
}
159165
},

src/tools/tidy/src/debug_artifacts.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,25 @@
22
33
use std::path::Path;
44

5+
use crate::diagnostics::{CheckId, DiagCtx};
56
use crate::walk::{filter_dirs, filter_not_rust, walk};
67

78
const GRAPHVIZ_POSTFLOW_MSG: &str = "`borrowck_graphviz_postflow` attribute in test";
89

9-
pub fn check(test_dir: &Path, bad: &mut bool) {
10+
pub fn check(test_dir: &Path, diag_ctx: DiagCtx) {
11+
let mut check = diag_ctx.start_check(CheckId::new("debug_artifacts").path(test_dir));
12+
1013
walk(
1114
test_dir,
1215
|path, _is_dir| filter_dirs(path) || filter_not_rust(path),
1316
&mut |entry, contents| {
1417
for (i, line) in contents.lines().enumerate() {
1518
if line.contains("borrowck_graphviz_postflow") {
16-
tidy_error!(
17-
bad,
18-
"{}:{}: {}",
19+
check.error(format!(
20+
"{}:{}: {GRAPHVIZ_POSTFLOW_MSG}",
1921
entry.path().display(),
20-
i + 1,
21-
GRAPHVIZ_POSTFLOW_MSG
22-
);
22+
i + 1
23+
));
2324
}
2425
}
2526
},

0 commit comments

Comments
 (0)