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