2 extern crate clippy_dev;
5 use clap::{App, Arg, SubCommand};
9 mod stderr_length_check;
18 let matches = App::new("Clippy developer tooling")
20 SubCommand::with_name("fmt")
21 .about("Run rustfmt on all projects and tests")
23 Arg::with_name("check")
25 .help("Use the rustfmt --check option"),
28 Arg::with_name("verbose")
31 .help("Echo commands run"),
35 SubCommand::with_name("update_lints")
36 .about("Updates lint registration and information from the source code")
39 * the lint count in README.md is correct\n \
40 * the changelog contains markdown link references at the bottom\n \
41 * all lint groups include the correct lints\n \
42 * lint modules in `clippy_lints/*` are visible in `src/lib.rs` via `pub mod`\n \
43 * all lints are registered in the lint store",
45 .arg(Arg::with_name("print-only").long("print-only").help(
46 "Print a table of lints to STDOUT. \
47 This does not include deprecated and internal lints. \
48 (Does not modify any files)",
51 Arg::with_name("check")
53 .help("Checks that util/dev update_lints has been run. Used on CI."),
57 Arg::with_name("limit-stderr-length")
58 .long("limit-stderr-length")
59 .help("Ensures that stderr files do not grow longer than a certain amount of lines."),
63 if matches.is_present("limit-stderr-length") {
64 stderr_length_check::check();
67 match matches.subcommand() {
68 ("fmt", Some(matches)) => {
69 fmt::run(matches.is_present("check"), matches.is_present("verbose"));
71 ("update_lints", Some(matches)) => {
72 if matches.is_present("print-only") {
74 } else if matches.is_present("check") {
75 update_lints(&UpdateMode::Check);
77 update_lints(&UpdateMode::Change);
85 let lint_list = gather_all();
86 let usable_lints: Vec<Lint> = Lint::usable_lints(lint_list).collect();
87 let lint_count = usable_lints.len();
88 let grouped_by_lint_group = Lint::by_lint_group(&usable_lints);
90 for (lint_group, mut lints) in grouped_by_lint_group {
91 if lint_group == "Deprecated" {
94 println!("\n## {}", lint_group);
96 lints.sort_by_key(|l| l.name.clone());
100 "* [{}]({}#{}) ({})",
102 clippy_dev::DOCS_LINK.clone(),
109 println!("there are {} lints", lint_count);
112 #[allow(clippy::too_many_lines)]
113 fn update_lints(update_mode: &UpdateMode) {
114 let lint_list: Vec<Lint> = gather_all().collect();
116 let usable_lints: Vec<Lint> = Lint::usable_lints(lint_list.clone().into_iter()).collect();
117 let lint_count = usable_lints.len();
119 let mut sorted_usable_lints = usable_lints.clone();
120 sorted_usable_lints.sort_by_key(|lint| lint.name.clone());
122 let mut file_change = replace_region_in_file(
123 "../src/lintlist/mod.rs",
127 update_mode == &UpdateMode::Change,
130 "pub const ALL_LINTS: [Lint; {}] = {:#?};",
131 sorted_usable_lints.len(),
135 .map(ToString::to_string)
141 file_change |= replace_region_in_file(
143 r#"\[There are \d+ lints included in this crate!\]\(https://rust-lang.github.io/rust-clippy/master/index.html\)"#,
146 update_mode == &UpdateMode::Change,
149 format!("[There are {} lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)", lint_count)
154 file_change |= replace_region_in_file(
156 "<!-- begin autogenerated links to lint list -->",
157 "<!-- end autogenerated links to lint list -->",
159 update_mode == &UpdateMode::Change,
160 || gen_changelog_lint_list(lint_list.clone()),
164 file_change |= replace_region_in_file(
165 "../clippy_lints/src/lib.rs",
166 "begin deprecated lints",
167 "end deprecated lints",
169 update_mode == &UpdateMode::Change,
170 || gen_deprecated(&lint_list),
174 file_change |= replace_region_in_file(
175 "../clippy_lints/src/lib.rs",
176 "begin register lints",
177 "end register lints",
179 update_mode == &UpdateMode::Change,
180 || gen_register_lint_list(&lint_list),
184 file_change |= replace_region_in_file(
185 "../clippy_lints/src/lib.rs",
186 "begin lints modules",
189 update_mode == &UpdateMode::Change,
190 || gen_modules_list(lint_list.clone()),
194 // Generate lists of lints in the clippy::all lint group
195 file_change |= replace_region_in_file(
196 "../clippy_lints/src/lib.rs",
197 r#"store.register_group\(true, "clippy::all""#,
200 update_mode == &UpdateMode::Change,
202 // clippy::all should only include the following lint groups:
203 let all_group_lints = usable_lints
207 l.group == "correctness" || l.group == "style" || l.group == "complexity" || l.group == "perf"
211 gen_lint_group_list(all_group_lints)
216 // Generate the list of lints for all other lint groups
217 for (lint_group, lints) in Lint::by_lint_group(&usable_lints) {
218 file_change |= replace_region_in_file(
219 "../clippy_lints/src/lib.rs",
220 &format!("store.register_group\\(true, \"clippy::{}\"", lint_group),
223 update_mode == &UpdateMode::Change,
224 || gen_lint_group_list(lints.clone()),
229 if update_mode == &UpdateMode::Check && file_change {
231 "Not all lints defined properly. \
232 Please run `util/dev update_lints` to make sure all lints are defined properly."
234 std::process::exit(1);