-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add warnings for nursery and preview rule selection #7210
Changes from all commits
5ecb833
dfb760b
0c69f82
726206e
ef961b7
167aeee
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,7 +27,7 @@ use ruff::settings::types::{ | |
Version, | ||
}; | ||
use ruff::settings::{defaults, resolve_per_file_ignores, AllSettings, CliSettings, Settings}; | ||
use ruff::{fs, warn_user_once_by_id, RuleSelector, RUFF_PKG_VERSION}; | ||
use ruff::{fs, warn_user, warn_user_once, warn_user_once_by_id, RuleSelector, RUFF_PKG_VERSION}; | ||
use ruff_cache::cache_dir; | ||
use rustc_hash::{FxHashMap, FxHashSet}; | ||
use shellexpand; | ||
|
@@ -460,7 +460,10 @@ impl Configuration { | |
let mut carryover_ignores: Option<&[RuleSelector]> = None; | ||
let mut carryover_unfixables: Option<&[RuleSelector]> = None; | ||
|
||
// Store selectors for displaying warnings | ||
let mut redirects = FxHashMap::default(); | ||
let mut deprecated_nursery_selectors = FxHashSet::default(); | ||
let mut ignored_preview_selectors = FxHashSet::default(); | ||
|
||
for selection in &self.rule_selections { | ||
// If a selection only specifies extend-select we cannot directly | ||
|
@@ -571,8 +574,7 @@ impl Configuration { | |
} | ||
} | ||
|
||
// We insert redirects into the hashmap so that we | ||
// can warn the users about remapped rule codes. | ||
// Check for selections that require a warning | ||
for selector in selection | ||
.select | ||
.iter() | ||
|
@@ -583,6 +585,29 @@ impl Configuration { | |
.chain(selection.unfixable.iter()) | ||
.chain(selection.extend_fixable.iter()) | ||
{ | ||
#[allow(deprecated)] | ||
if matches!(selector, RuleSelector::Nursery) { | ||
let suggestion = if preview.is_disabled() { | ||
"Use the `--preview` flag instead." | ||
} else { | ||
"Use the `PREVIEW` selector instead." | ||
}; | ||
warn_user_once!("The `NURSERY` selector has been deprecated. {suggestion}"); | ||
} | ||
|
||
if preview.is_disabled() { | ||
if let RuleSelector::Rule { prefix, .. } = selector { | ||
if prefix.rules().any(|rule| rule.is_nursery()) { | ||
deprecated_nursery_selectors.insert(selector); | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this like: you selected |
||
|
||
// Check if the selector is empty because preview mode is disabled | ||
if selector.rules(PreviewMode::Disabled).next().is_none() { | ||
ignored_preview_selectors.insert(selector); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cool so this is like -- you selected There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep! I think the exact code would warn too. We could make this "safer" by adding There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can't write an integration test for exact codes yet since we don't have any preview rules. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And this is like -- you selected There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do both warnings show if you select There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mean like https://github.com/astral-sh/ruff/pull/7210/files#diff-92738d4e248765a1e48e3c930a03e20ed306f9b0c23dd67ad72912133dbb10f2R289-R306? Or if you select CPY and CPY001? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I meant the former |
||
} | ||
|
||
if let RuleSelector::Prefix { | ||
prefix, | ||
redirected_from: Some(redirect_from), | ||
|
@@ -603,6 +628,18 @@ impl Configuration { | |
); | ||
} | ||
|
||
for selection in deprecated_nursery_selectors { | ||
let (prefix, code) = selection.prefix_and_code(); | ||
warn_user!("Selection of nursery rule `{prefix}{code}` without the `--preview` flag is deprecated.",); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because this doesn't use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah but I'd have to construct an id string like "nursery-{prefix}{code}", is that okay? I was thinking of adding a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that's okay (to add an ID like that) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But I think the ID has to be a static string so that may not work... |
||
} | ||
Comment on lines
+631
to
+634
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The redirect warning code has a comment that says this should be in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd vote to just remove that TODO -- I can't remember why it's there. |
||
|
||
for selection in ignored_preview_selectors { | ||
let (prefix, code) = selection.prefix_and_code(); | ||
warn_user!( | ||
"Selection `{prefix}{code}` has no effect because the `--preview` flag was not included.", | ||
); | ||
} | ||
|
||
let mut rules = RuleTable::empty(); | ||
|
||
for rule in select_set { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What will happen to this test when E225 gets promoted to stable? (i don't have good answer for testing this)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great question, do we choose a new code? Should we have a couple of rules in a "TEST" category that do nothing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm looking into this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not working... but an idea zanie/rule-warning...zanie/rule-tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit hesitant about adding test-only rules. We would need to filter them out in documentation, schema generation and prevent they can be selected in production (but then, we want them to be selectable in tests).
We could add the category behind a rust feature and make this an integration test (integration tests can require features), but this still suffers from the above-mentioned problems, although it has some more safeguards around it.
To me this is an inherent downside of our statically generated rule schema (instead of deriving a
Rule
array that has somewhat weaker keys which would allow you to mock out the rules).I don't have a good solution to propose that doesn't require changing our rule structure or abstracting some of the logic by a trait that then allows overriding whether a rule is preview or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't the
#[cfg(test)]
approach address most of those concerns?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can also wait and see how much of a burden it is to maintain the tests as-is. I don't like it though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
iirc
#[cfg(test)]
is only available in the same crate and not across crates (https://users.rust-lang.org/t/what-are-the-rules-for-cfg-test/54122/2), so e.g.ruff
cfg(test)
rules would not be available inruff_cli
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resources: