]> git.proxmox.com Git - rustc.git/blame - src/tools/clippy/tests/lint_message_convention.rs
New upstream version 1.53.0+dfsg1
[rustc.git] / src / tools / clippy / tests / lint_message_convention.rs
CommitLineData
f20569fa
XL
1use std::ffi::OsStr;
2use std::path::PathBuf;
3
4use regex::RegexSet;
5
6#[derive(Debug)]
7struct Message {
8 path: PathBuf,
9 bad_lines: Vec<String>,
10}
11
12impl Message {
13 fn new(path: PathBuf) -> Self {
14 let content: String = std::fs::read_to_string(&path).unwrap();
15 // we don't want the first letter after "error: ", "help: " ... to be capitalized
16 // also no puncutation (except for "?" ?) at the end of a line
17 let regex_set: RegexSet = RegexSet::new(&[
18 r"error: [A-Z]",
19 r"help: [A-Z]",
20 r"warning: [A-Z]",
21 r"note: [A-Z]",
22 r"try this: [A-Z]",
23 r"error: .*[.!]$",
24 r"help: .*[.!]$",
25 r"warning: .*[.!]$",
26 r"note: .*[.!]$",
27 r"try this: .*[.!]$",
28 ])
29 .unwrap();
30
31 // sometimes the first character is capitalized and it is legal (like in "C-like enum variants") or
32 // we want to ask a question ending in "?"
33 let exceptions_set: RegexSet = RegexSet::new(&[
34 r".*C-like enum variant discriminant is not portable to 32-bit targets",
35 r".*did you mean `unix`?",
36 r".*the arguments may be inverted...",
37 r".*Intel x86 assembly syntax used",
38 r".*AT&T x86 assembly syntax used",
39 r".*remove .*the return type...",
40 r"note: Clippy version: .*",
41 r"the compiler unexpectedly panicked. this is a bug.",
42 ])
43 .unwrap();
44
45 let bad_lines = content
46 .lines()
47 .filter(|line| regex_set.matches(line).matched_any())
48 // ignore exceptions
49 .filter(|line| !exceptions_set.matches(line).matched_any())
50 .map(ToOwned::to_owned)
51 .collect::<Vec<String>>();
52
53 Message { path, bad_lines }
54 }
55}
56
57#[test]
58fn lint_message_convention() {
59 // disable the test inside the rustc test suite
60 if option_env!("RUSTC_TEST_SUITE").is_some() {
61 return;
62 }
63
64 // make sure that lint messages:
65 // * are not capitalized
66 // * don't have puncuation at the end of the last sentence
67
68 // these directories have interesting tests
69 let test_dirs = ["ui", "ui-cargo", "ui-internal", "ui-toml"]
70 .iter()
71 .map(PathBuf::from)
72 .map(|p| {
73 let base = PathBuf::from("tests");
74 base.join(p)
75 });
76
77 // gather all .stderr files
78 let tests = test_dirs
79 .flat_map(|dir| {
80 std::fs::read_dir(dir)
81 .expect("failed to read dir")
82 .map(|direntry| direntry.unwrap().path())
83 })
84 .filter(|file| matches!(file.extension().map(OsStr::to_str), Some(Some("stderr"))));
85
86 // get all files that have any "bad lines" in them
87 let bad_tests: Vec<Message> = tests
88 .map(Message::new)
89 .filter(|message| !message.bad_lines.is_empty())
90 .collect();
91
cdc7bbd5 92 for message in &bad_tests {
f20569fa
XL
93 eprintln!(
94 "error: the test '{}' contained the following nonconforming lines :",
95 message.path.display()
96 );
97 message.bad_lines.iter().for_each(|line| eprintln!("{}", line));
98 eprintln!("\n\n");
cdc7bbd5 99 }
f20569fa
XL
100
101 eprintln!(
102 "\n\n\nLint message should not start with a capital letter and should not have punctuation at the end of the message unless multiple sentences are needed."
103 );
104 eprintln!("Check out the rustc-dev-guide for more information:");
105 eprintln!("https://rustc-dev-guide.rust-lang.org/diagnostics.html#diagnostic-structure\n\n\n");
106
107 assert!(bad_tests.is_empty());
108}