about summary refs log tree commit diff
path: root/clippy_dev
diff options
context:
space:
mode:
authorMichael Wright <mikerite@lavabit.com>2021-09-18 06:43:39 +0200
committerMichael Wright <mikerite@lavabit.com>2021-09-29 05:43:25 +0200
commit50ea37061937acf9c912e0088ce48783926562a1 (patch)
tree7f586ed3a266e01f48caed3e827949d8a49a5259 /clippy_dev
parent685b77316f3fbc35bfe1982803df7133cd2cb36d (diff)
downloadrust-50ea37061937acf9c912e0088ce48783926562a1.tar.gz
rust-50ea37061937acf9c912e0088ce48783926562a1.zip
Move code generated by `update_lints` to includes
Diffstat (limited to 'clippy_dev')
-rw-r--r--clippy_dev/src/lib.rs68
-rw-r--r--clippy_dev/src/update_lints.rs116
2 files changed, 100 insertions, 84 deletions
diff --git a/clippy_dev/src/lib.rs b/clippy_dev/src/lib.rs
index e05db7af586..8f0356c028b 100644
--- a/clippy_dev/src/lib.rs
+++ b/clippy_dev/src/lib.rs
@@ -100,11 +100,24 @@ impl Lint {
 
 /// Generates the Vec items for `register_lint_group` calls in `clippy_lints/src/lib.rs`.
 #[must_use]
-pub fn gen_lint_group_list<'a>(lints: impl Iterator<Item = &'a Lint>) -> Vec<String> {
-    lints
-        .map(|l| format!("        LintId::of({}::{}),", l.module, l.name.to_uppercase()))
-        .sorted()
-        .collect::<Vec<String>>()
+pub fn gen_lint_group_list<'a>(group_name: &str, lints: impl Iterator<Item = &'a Lint>) -> Vec<String> {
+    let header = format!(
+        r#"store.register_group(true, "clippy::{0}", Some("clippy_{0}"), vec!["#,
+        group_name
+    );
+    let footer = "])".to_string();
+
+    let mut result = vec![header];
+
+    result.extend(
+        lints
+            .map(|l| format!("LintId::of({}::{}),", l.module, l.name.to_uppercase()))
+            .sorted(),
+    );
+
+    result.push(footer);
+
+    result
 }
 
 /// Generates the `pub mod module_name` list in `clippy_lints/src/lib.rs`.
@@ -130,21 +143,22 @@ pub fn gen_changelog_lint_list<'a>(lints: impl Iterator<Item = &'a Lint>) -> Vec
 /// Generates the `register_removed` code in `./clippy_lints/src/lib.rs`.
 #[must_use]
 pub fn gen_deprecated<'a>(lints: impl Iterator<Item = &'a Lint>) -> Vec<String> {
-    lints
-        .flat_map(|l| {
-            l.deprecation
-                .clone()
-                .map(|depr_text| {
-                    vec![
-                        "    store.register_removed(".to_string(),
-                        format!("        \"clippy::{}\",", l.name),
-                        format!("        \"{}\",", depr_text),
-                        "    );".to_string(),
-                    ]
-                })
-                .expect("only deprecated lints should be passed")
-        })
-        .collect::<Vec<String>>()
+    let mut result = vec!["{".to_string()];
+    result.extend(lints.flat_map(|l| {
+        l.deprecation
+            .clone()
+            .map(|depr_text| {
+                vec![
+                    "    store.register_removed(".to_string(),
+                    format!("        \"clippy::{}\",", l.name),
+                    format!("        \"{}\",", depr_text),
+                    "    );".to_string(),
+                ]
+            })
+            .expect("only deprecated lints should be passed")
+    }));
+    result.push("}".to_string());
+    result
 }
 
 #[must_use]
@@ -153,7 +167,7 @@ pub fn gen_register_lint_list<'a>(
     usable_lints: impl Iterator<Item = &'a Lint>,
 ) -> Vec<String> {
     let header = "    store.register_lints(&[".to_string();
-    let footer = "    ]);".to_string();
+    let footer = "    ])".to_string();
     let internal_lints = internal_lints
         .sorted_by_key(|l| format!("        {}::{},", l.module, l.name.to_uppercase()))
         .map(|l| {
@@ -511,6 +525,7 @@ fn test_gen_deprecated() {
         ),
     ];
     let expected: Vec<String> = vec![
+        "{",
         "    store.register_removed(",
         "        \"clippy::should_assert_eq\",",
         "        \"has been superseded by should_assert_eq2\",",
@@ -519,6 +534,7 @@ fn test_gen_deprecated() {
         "        \"clippy::another_deprecated\",",
         "        \"will be removed\",",
         "    );",
+        "}",
     ]
     .into_iter()
     .map(String::from)
@@ -551,9 +567,11 @@ fn test_gen_lint_group_list() {
         Lint::new("internal", "internal_style", "abc", None, "module_name"),
     ];
     let expected = vec![
-        "        LintId::of(module_name::ABC),".to_string(),
-        "        LintId::of(module_name::INTERNAL),".to_string(),
-        "        LintId::of(module_name::SHOULD_ASSERT_EQ),".to_string(),
+        "store.register_group(true, \"clippy::group1\", Some(\"clippy_group1\"), vec![",
+        "LintId::of(module_name::ABC),",
+        "LintId::of(module_name::INTERNAL),",
+        "LintId::of(module_name::SHOULD_ASSERT_EQ),",
+        "])",
     ];
-    assert_eq!(expected, gen_lint_group_list(lints.iter()));
+    assert_eq!(expected, gen_lint_group_list("group1", lints.iter()));
 }
diff --git a/clippy_dev/src/update_lints.rs b/clippy_dev/src/update_lints.rs
index db467c26f15..ba550d492fc 100644
--- a/clippy_dev/src/update_lints.rs
+++ b/clippy_dev/src/update_lints.rs
@@ -2,6 +2,7 @@ use crate::{
     gather_all, gen_changelog_lint_list, gen_deprecated, gen_lint_group_list, gen_modules_list, gen_register_lint_list,
     replace_region_in_file, Lint, DOCS_LINK,
 };
+use std::fs;
 use std::path::Path;
 
 #[derive(Clone, Copy, PartialEq)]
@@ -10,6 +11,15 @@ pub enum UpdateMode {
     Change,
 }
 
+/// Runs the `update_lints` command.
+///
+/// This updates various generated values from the lint source code.
+///
+/// `update_mode` indicates if the files should be updated or if updates should be checked for.
+///
+/// # Panics
+///
+/// Panics if a file path could not read from or then written to
 #[allow(clippy::too_many_lines)]
 pub fn run(update_mode: UpdateMode) {
     let lint_list: Vec<Lint> = gather_all().collect();
@@ -52,45 +62,18 @@ pub fn run(update_mode: UpdateMode) {
     )
     .changed;
 
-    file_change |= replace_region_in_file(
-        Path::new("clippy_lints/src/lib.rs"),
-        "begin deprecated lints",
-        "end deprecated lints",
-        false,
-        update_mode == UpdateMode::Change,
-        || gen_deprecated(deprecated_lints.iter()),
-    )
-    .changed;
-
-    file_change |= replace_region_in_file(
-        Path::new("clippy_lints/src/lib.rs"),
-        "begin register lints",
-        "end register lints",
-        false,
-        update_mode == UpdateMode::Change,
-        || gen_register_lint_list(internal_lints.iter(), usable_lints.iter()),
-    )
-    .changed;
-
-    file_change |= replace_region_in_file(
-        Path::new("clippy_lints/src/lib.rs"),
-        "begin lints modules",
-        "end lints modules",
-        false,
-        update_mode == UpdateMode::Change,
-        || gen_modules_list(usable_lints.iter()),
-    )
-    .changed;
+    if file_change && update_mode == UpdateMode::Check {
+        exit_with_failure();
+    }
 
-    // Generate lists of lints in the clippy::all lint group
-    file_change |= replace_region_in_file(
-        Path::new("clippy_lints/src/lib.rs"),
-        r#"store.register_group\(true, "clippy::all""#,
-        r#"\]\);"#,
-        false,
-        update_mode == UpdateMode::Change,
-        || {
-            // clippy::all should only include the following lint groups:
+    for (name, lines) in [
+        ("mods", gen_modules_list(usable_lints.iter())),
+        ("deprecated", gen_deprecated(deprecated_lints.iter())),
+        (
+            "register_lints",
+            gen_register_lint_list(internal_lints.iter(), usable_lints.iter()),
+        ),
+        ("register_all", {
             let all_group_lints = usable_lints.iter().filter(|l| {
                 matches!(
                     &*l.group,
@@ -98,30 +81,18 @@ pub fn run(update_mode: UpdateMode) {
                 )
             });
 
-            gen_lint_group_list(all_group_lints)
-        },
-    )
-    .changed;
-
-    // Generate the list of lints for all other lint groups
-    for (lint_group, lints) in Lint::by_lint_group(usable_lints.into_iter().chain(internal_lints)) {
-        file_change |= replace_region_in_file(
-            Path::new("clippy_lints/src/lib.rs"),
-            &format!("store.register_group\\(true, \"clippy::{}\"", lint_group),
-            r#"\]\);"#,
-            false,
-            update_mode == UpdateMode::Change,
-            || gen_lint_group_list(lints.iter()),
-        )
-        .changed;
+            gen_lint_group_list("all", all_group_lints)
+        }),
+    ] {
+        process_file(&format!("clippy_lints/src/lib.{}.rs", name), update_mode, &lines[..]);
     }
 
-    if update_mode == UpdateMode::Check && file_change {
-        println!(
-            "Not all lints defined properly. \
-             Please run `cargo dev update_lints` to make sure all lints are defined properly."
+    for (lint_group, lints) in Lint::by_lint_group(usable_lints.into_iter().chain(internal_lints)) {
+        process_file(
+            &format!("clippy_lints/src/lib.register_{}.rs", lint_group),
+            update_mode,
+            &gen_lint_group_list(&lints.get(0).expect("group non-empty").group, lints.iter())[..],
         );
-        std::process::exit(1);
     }
 }
 
@@ -150,3 +121,30 @@ pub fn print_lints() {
 fn round_to_fifty(count: usize) -> usize {
     count / 50 * 50
 }
+
+fn process_file(path: impl AsRef<Path>, update_mode: UpdateMode, new_lines: &[String]) {
+    let mut new_content = "// This file was generated by `cargo dev update_lints`.\n\
+                       // Use that command to update this file and do not edit by hand.\n\
+                       // Manual edits will be overwritten.\n\n"
+        .to_string();
+    new_content.push_str(&new_lines.join("\n"));
+
+    if update_mode == UpdateMode::Check {
+        let old_content =
+            fs::read_to_string(&path).unwrap_or_else(|e| panic!("Cannot read from {}: {}", path.as_ref().display(), e));
+        if new_content != old_content {
+            exit_with_failure();
+        }
+    } else {
+        fs::write(&path, new_content.as_bytes())
+            .unwrap_or_else(|e| panic!("Cannot write to {}: {}", path.as_ref().display(), e));
+    }
+}
+
+fn exit_with_failure() {
+    println!(
+        "Not all lints defined properly. \
+                 Please run `cargo dev update_lints` to make sure all lints are defined properly."
+    );
+    std::process::exit(1);
+}