Add rule removal infrastructure (#9691)

Similar to https://github.com/astral-sh/ruff/pull/9689 — retains removed
rules for better error messages and documentation but removed rules
_cannot_ be used in any context.

Removes PLR1706 as a useful test case and something we want to
accomplish in #9680 anyway. The rule was in preview so we do not need to
deprecate it first.

Closes https://github.com/astral-sh/ruff/issues/9007

## Test plan

<img width="1110" alt="Rules table"
src="ac9fa682-623c-44aa-8e51-d8ab0d308355">

<img width="1110" alt="Rule page"
src="05850b2d-7ca5-49bb-8df8-bb931bab25cd">
This commit is contained in:
Zanie Blue 2024-01-30 11:45:49 -06:00
parent a0ef087e73
commit e0bc08a758
13 changed files with 127 additions and 411 deletions

View file

@ -756,6 +756,7 @@ impl LintConfiguration {
let mut redirects = FxHashMap::default();
let mut deprecated_nursery_selectors = FxHashSet::default();
let mut deprecated_selectors = FxHashSet::default();
let mut removed_selectors = FxHashSet::default();
let mut ignored_preview_selectors = FxHashSet::default();
// Track which docstring rules are specifically enabled
@ -922,6 +923,13 @@ impl LintConfiguration {
}
}
// Removed rules
if let RuleSelector::Rule { prefix, .. } = selector {
if prefix.rules().any(|rule| rule.is_removed()) {
removed_selectors.insert(selector);
}
}
// Redirected rules
if let RuleSelector::Prefix {
prefix,
@ -933,6 +941,29 @@ impl LintConfiguration {
}
}
let removed_selectors = removed_selectors.iter().collect::<Vec<_>>();
match removed_selectors.as_slice() {
[] => (),
[selection] => {
let (prefix, code) = selection.prefix_and_code();
return Err(anyhow!(
"Rule `{prefix}{code}` was removed and cannot be selected."
));
}
[..] => {
let mut message =
"The following rules have been removed and cannot be selected:".to_string();
for selection in removed_selectors {
let (prefix, code) = selection.prefix_and_code();
message.push_str("\n - ");
message.push_str(prefix);
message.push_str(code);
}
message.push('\n');
return Err(anyhow!(message));
}
}
for (from, target) in redirects {
// TODO(martin): This belongs into the ruff crate.
warn_user_once_by_id!(
@ -1423,7 +1454,6 @@ mod tests {
use std::str::FromStr;
const PREVIEW_RULES: &[Rule] = &[
Rule::AndOrTernary,
Rule::AssignmentInAssert,
Rule::DirectLoggerInstantiation,
Rule::InvalidGetLoggerArgument,