clippy_dev: remove the need for markers when bumping the version

This commit is contained in:
Jason Newcomb
2025-04-16 20:12:17 -04:00
parent c97b4761d8
commit 9d47e0c8ce
6 changed files with 105 additions and 47 deletions
-2
View File
@@ -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"
-2
View File
@@ -1,8 +1,6 @@
[package]
name = "clippy_config"
# begin autogenerated version
version = "0.1.89"
# end autogenerated version
edition = "2024"
publish = false
+13 -11
View File
@@ -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))
}
});
}
}
+92 -28
View File
@@ -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 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
}
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 @@ pub fn search_for_manifest() -> Self {
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 };
}
}
}
-2
View File
@@ -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"
-2
View File
@@ -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"