about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJason Newcomb <jsnewcomb@pm.me>2025-04-16 20:12:17 -0400
committerJason Newcomb <jsnewcomb@pm.me>2025-05-17 04:27:39 -0400
commit9d47e0c8ce80d8251fa944d41bdc7f9b8b6d0c8b (patch)
treeeb04f56c8b0e78b3dce4a573c9c94e115e18ec4a
parentc97b4761d8790e61b84ba7e2d26ddb787a4b88a1 (diff)
downloadrust-9d47e0c8ce80d8251fa944d41bdc7f9b8b6d0c8b.tar.gz
rust-9d47e0c8ce80d8251fa944d41bdc7f9b8b6d0c8b.zip
clippy_dev: remove the need for markers when bumping the version
-rw-r--r--Cargo.toml2
-rw-r--r--clippy_config/Cargo.toml2
-rw-r--r--clippy_dev/src/release.rs24
-rw-r--r--clippy_dev/src/utils.rs120
-rw-r--r--clippy_lints/Cargo.toml2
-rw-r--r--clippy_utils/Cargo.toml2
6 files changed, 105 insertions, 47 deletions
diff --git a/Cargo.toml b/Cargo.toml
index b6a1b9314c6..2da350ba44e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,8 +1,6 @@
 [package]
 name = "clippy"
-# begin autogenerated version
 version = "0.1.89"
-# end autogenerated version
 description = "A bunch of helpful lints to avoid common pitfalls in Rust"
 repository = "https://github.com/rust-lang/rust-clippy"
 readme = "README.md"
diff --git a/clippy_config/Cargo.toml b/clippy_config/Cargo.toml
index 1134b0e97af..0606245f990 100644
--- a/clippy_config/Cargo.toml
+++ b/clippy_config/Cargo.toml
@@ -1,8 +1,6 @@
 [package]
 name = "clippy_config"
-# begin autogenerated version
 version = "0.1.89"
-# end autogenerated version
 edition = "2024"
 publish = false
 
diff --git a/clippy_dev/src/release.rs b/clippy_dev/src/release.rs
index d3b1a7ff320..62c1bee8185 100644
--- a/clippy_dev/src/release.rs
+++ b/clippy_dev/src/release.rs
@@ -1,4 +1,4 @@
-use crate::utils::{FileUpdater, Version, update_text_region_fn};
+use crate::utils::{FileUpdater, UpdateStatus, Version, parse_cargo_package};
 use std::fmt::Write;
 
 static CARGO_TOML_FILES: &[&str] = &[
@@ -13,15 +13,17 @@ pub fn bump_version(mut version: Version) {
 
     let mut updater = FileUpdater::default();
     for file in CARGO_TOML_FILES {
-        updater.update_file(
-            file,
-            &mut update_text_region_fn(
-                "# begin autogenerated version\n",
-                "# end autogenerated version",
-                |dst| {
-                    writeln!(dst, "version = \"{}\"", version.toml_display()).unwrap();
-                },
-            ),
-        );
+        updater.update_file(file, &mut |_, src, dst| {
+            let package = parse_cargo_package(src);
+            if package.version_range.is_empty() {
+                dst.push_str(src);
+                UpdateStatus::Unchanged
+            } else {
+                dst.push_str(&src[..package.version_range.start]);
+                write!(dst, "\"{}\"", version.toml_display()).unwrap();
+                dst.push_str(&src[package.version_range.end..]);
+                UpdateStatus::from_changed(src.get(package.version_range.clone()) != dst.get(package.version_range))
+            }
+        });
     }
 }
diff --git a/clippy_dev/src/utils.rs b/clippy_dev/src/utils.rs
index fb2e25e655d..7fab64eb7aa 100644
--- a/clippy_dev/src/utils.rs
+++ b/clippy_dev/src/utils.rs
@@ -1,4 +1,5 @@
 use core::fmt::{self, Display};
+use core::ops::Range;
 use core::slice;
 use core::str::FromStr;
 use rustc_lexer::{self as lexer, FrontmatterAllowed};
@@ -166,9 +167,85 @@ impl Version {
     }
 }
 
+enum TomlPart<'a> {
+    Table(&'a str),
+    Value(&'a str, &'a str),
+}
+
+fn toml_iter(s: &str) -> impl Iterator<Item = (usize, TomlPart<'_>)> {
+    let mut pos = 0;
+    s.split('\n')
+        .map(move |s| {
+            let x = pos;
+            pos += s.len() + 1;
+            (x, s)
+        })
+        .filter_map(|(pos, s)| {
+            if let Some(s) = s.strip_prefix('[') {
+                s.split_once(']').map(|(name, _)| (pos, TomlPart::Table(name)))
+            } else if matches!(
+                s.as_bytes().get(0),
+                Some(b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9' | b'_')
+            ) {
+                s.split_once('=').map(|(key, value)| (pos, TomlPart::Value(key, value)))
+            } else {
+                None
+            }
+        })
+}
+
+pub struct CargoPackage<'a> {
+    pub name: &'a str,
+    pub version_range: Range<usize>,
+    pub not_a_platform_range: Range<usize>,
+}
+
+pub fn parse_cargo_package(s: &str) -> CargoPackage<'_> {
+    let mut in_package = false;
+    let mut in_platform_deps = false;
+    let mut name = "";
+    let mut version_range = 0..0;
+    let mut not_a_platform_range = 0..0;
+    for (offset, part) in toml_iter(s) {
+        match part {
+            TomlPart::Table(name) => {
+                if in_platform_deps {
+                    not_a_platform_range.end = offset;
+                }
+                in_package = false;
+                in_platform_deps = false;
+
+                match name.trim() {
+                    "package" => in_package = true,
+                    "target.'cfg(NOT_A_PLATFORM)'.dependencies" => {
+                        in_platform_deps = true;
+                        not_a_platform_range.start = offset;
+                    },
+                    _ => {},
+                }
+            },
+            TomlPart::Value(key, value) if in_package => match key.trim_end() {
+                "name" => name = value.trim(),
+                "version" => {
+                    version_range.start = offset + (value.len() - value.trim().len()) + key.len() + 1;
+                    version_range.end = offset + key.len() + value.trim_end().len() + 1;
+                },
+                _ => {},
+            },
+            _ => {},
+        }
+    }
+    CargoPackage {
+        name,
+        version_range,
+        not_a_platform_range,
+    }
+}
+
 pub struct ClippyInfo {
     pub path: PathBuf,
     pub version: Version,
+    pub has_intellij_hook: bool,
 }
 impl ClippyInfo {
     #[must_use]
@@ -178,35 +255,22 @@ impl ClippyInfo {
         loop {
             path.push("Cargo.toml");
             if let Some(mut file) = File::open_if_exists(&path, OpenOptions::new().read(true)) {
-                let mut in_package = false;
-                let mut is_clippy = false;
-                let mut version: Option<Version> = None;
-
-                // Ad-hoc parsing to avoid dependencies. We control all the file so this
-                // isn't actually a problem
-                for line in file.read_to_cleared_string(&mut buf).lines() {
-                    if line.starts_with('[') {
-                        in_package = line.starts_with("[package]");
-                    } else if in_package && let Some((name, value)) = line.split_once('=') {
-                        match name.trim() {
-                            "name" => is_clippy = value.trim() == "\"clippy\"",
-                            "version"
-                                if let Some(value) = value.trim().strip_prefix('"')
-                                    && let Some(value) = value.strip_suffix('"') =>
-                            {
-                                version = value.parse().ok();
-                            },
-                            _ => {},
-                        }
-                    }
-                }
-
-                if is_clippy {
-                    let Some(version) = version else {
+                file.read_to_cleared_string(&mut buf);
+                let package = parse_cargo_package(&buf);
+                if package.name == "\"clippy\"" {
+                    if let Some(version) = buf[package.version_range].strip_prefix('"')
+                        && let Some(version) = version.strip_suffix('"')
+                        && let Ok(version) = version.parse()
+                    {
+                        path.pop();
+                        return ClippyInfo {
+                            path,
+                            version,
+                            has_intellij_hook: !package.not_a_platform_range.is_empty(),
+                        };
+                    } else {
                         panic!("error reading clippy version from {}", file.path.display());
-                    };
-                    path.pop();
-                    return ClippyInfo { path, version };
+                    }
                 }
             }
 
diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml
index 7e3cb404247..39e4e2e365e 100644
--- a/clippy_lints/Cargo.toml
+++ b/clippy_lints/Cargo.toml
@@ -1,8 +1,6 @@
 [package]
 name = "clippy_lints"
-# begin autogenerated version
 version = "0.1.89"
-# end autogenerated version
 description = "A bunch of helpful lints to avoid common pitfalls in Rust"
 repository = "https://github.com/rust-lang/rust-clippy"
 readme = "README.md"
diff --git a/clippy_utils/Cargo.toml b/clippy_utils/Cargo.toml
index ac970e1c4b0..615c0995e8b 100644
--- a/clippy_utils/Cargo.toml
+++ b/clippy_utils/Cargo.toml
@@ -1,8 +1,6 @@
 [package]
 name = "clippy_utils"
-# begin autogenerated version
 version = "0.1.89"
-# end autogenerated version
 edition = "2024"
 description = "Helpful tools for writing lints, provided as they are used in Clippy"
 repository = "https://github.com/rust-lang/rust-clippy"