]> git.lizzy.rs Git - rust.git/blob - clippy_dev/src/update_lints.rs
Move update_lints logic to its own module
[rust.git] / clippy_dev / src / update_lints.rs
1 use crate::{
2     gather_all, gen_changelog_lint_list, gen_deprecated, gen_lint_group_list, gen_modules_list, gen_register_lint_list,
3     replace_region_in_file, Lint, DOCS_LINK,
4 };
5 use std::path::Path;
6
7 #[derive(Clone, Copy, PartialEq)]
8 pub enum UpdateMode {
9     Check,
10     Change,
11 }
12
13 #[allow(clippy::too_many_lines)]
14 pub fn run(update_mode: UpdateMode) {
15     let lint_list: Vec<Lint> = gather_all().collect();
16
17     let internal_lints = Lint::internal_lints(lint_list.clone().into_iter());
18
19     let usable_lints: Vec<Lint> = Lint::usable_lints(lint_list.clone().into_iter()).collect();
20     let usable_lint_count = usable_lints.len();
21
22     let mut sorted_usable_lints = usable_lints.clone();
23     sorted_usable_lints.sort_by_key(|lint| lint.name.clone());
24
25     let mut file_change = replace_region_in_file(
26         Path::new("src/lintlist/mod.rs"),
27         "begin lint list",
28         "end lint list",
29         false,
30         update_mode == UpdateMode::Change,
31         || {
32             format!(
33                 "pub const ALL_LINTS: [Lint; {}] = {:#?};",
34                 sorted_usable_lints.len(),
35                 sorted_usable_lints
36             )
37             .lines()
38             .map(ToString::to_string)
39             .collect::<Vec<_>>()
40         },
41     )
42     .changed;
43
44     file_change |= replace_region_in_file(
45         Path::new("README.md"),
46         &format!(r#"\[There are \d+ lints included in this crate!\]\({}\)"#, DOCS_LINK),
47         "",
48         true,
49         update_mode == UpdateMode::Change,
50         || {
51             vec![format!(
52                 "[There are {} lints included in this crate!]({})",
53                 usable_lint_count, DOCS_LINK
54             )]
55         },
56     )
57     .changed;
58
59     file_change |= replace_region_in_file(
60         Path::new("CHANGELOG.md"),
61         "<!-- begin autogenerated links to lint list -->",
62         "<!-- end autogenerated links to lint list -->",
63         false,
64         update_mode == UpdateMode::Change,
65         || gen_changelog_lint_list(lint_list.clone()),
66     )
67     .changed;
68
69     file_change |= replace_region_in_file(
70         Path::new("clippy_lints/src/lib.rs"),
71         "begin deprecated lints",
72         "end deprecated lints",
73         false,
74         update_mode == UpdateMode::Change,
75         || gen_deprecated(&lint_list),
76     )
77     .changed;
78
79     file_change |= replace_region_in_file(
80         Path::new("clippy_lints/src/lib.rs"),
81         "begin register lints",
82         "end register lints",
83         false,
84         update_mode == UpdateMode::Change,
85         || gen_register_lint_list(&lint_list),
86     )
87     .changed;
88
89     file_change |= replace_region_in_file(
90         Path::new("clippy_lints/src/lib.rs"),
91         "begin lints modules",
92         "end lints modules",
93         false,
94         update_mode == UpdateMode::Change,
95         || gen_modules_list(lint_list.clone()),
96     )
97     .changed;
98
99     // Generate lists of lints in the clippy::all lint group
100     file_change |= replace_region_in_file(
101         Path::new("clippy_lints/src/lib.rs"),
102         r#"store.register_group\(true, "clippy::all""#,
103         r#"\]\);"#,
104         false,
105         update_mode == UpdateMode::Change,
106         || {
107             // clippy::all should only include the following lint groups:
108             let all_group_lints = usable_lints
109                 .clone()
110                 .into_iter()
111                 .filter(|l| {
112                     l.group == "correctness" || l.group == "style" || l.group == "complexity" || l.group == "perf"
113                 })
114                 .collect();
115
116             gen_lint_group_list(all_group_lints)
117         },
118     )
119     .changed;
120
121     // Generate the list of lints for all other lint groups
122     for (lint_group, lints) in Lint::by_lint_group(usable_lints.into_iter().chain(internal_lints)) {
123         file_change |= replace_region_in_file(
124             Path::new("clippy_lints/src/lib.rs"),
125             &format!("store.register_group\\(true, \"clippy::{}\"", lint_group),
126             r#"\]\);"#,
127             false,
128             update_mode == UpdateMode::Change,
129             || gen_lint_group_list(lints.clone()),
130         )
131         .changed;
132     }
133
134     if update_mode == UpdateMode::Check && file_change {
135         println!(
136             "Not all lints defined properly. \
137              Please run `cargo dev update_lints` to make sure all lints are defined properly."
138         );
139         std::process::exit(1);
140     }
141 }
142
143 pub fn print_lints() {
144     let lint_list = gather_all();
145     let usable_lints: Vec<Lint> = Lint::usable_lints(lint_list).collect();
146     let usable_lint_count = usable_lints.len();
147     let grouped_by_lint_group = Lint::by_lint_group(usable_lints.into_iter());
148
149     for (lint_group, mut lints) in grouped_by_lint_group {
150         if lint_group == "Deprecated" {
151             continue;
152         }
153         println!("\n## {}", lint_group);
154
155         lints.sort_by_key(|l| l.name.clone());
156
157         for lint in lints {
158             println!("* [{}]({}#{}) ({})", lint.name, DOCS_LINK, lint.name, lint.desc);
159         }
160     }
161
162     println!("there are {} lints", usable_lint_count);
163 }