Skip to content

Commit 3e29d23

Browse files
authored
fix(linter): use aliases when parsing cli rules (#14912)
- Fixes #14906 #### What went wrong - `parse_rule_key` has the logic for aliasing, and it is called by `OxlintRules`, but only during deserialization. - `CliRunner`, via `ConfigStoreBuilder`, instantiates `OxlintRules` directly. No post processing, aliasing doesn't take place. #### Fix - Aliasing logic in `parse_rule_key` is split off as `unalias_plugin_name`. - `unalias_plugin_name` is now called by `ConfigStoreBuilder`. - `LintFilterKind::parse` seemed like a better place at first, but lifetimes required cloning.
1 parent b94b6aa commit 3e29d23

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

crates/oxc_linter/src/config/config_builder.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ impl ConfigStoreBuilder {
305305
self.upsert_where(severity, |r| r.category() == *category);
306306
}
307307
LintFilterKind::Rule(plugin, rule) => {
308+
let (plugin, rule) = super::rules::unalias_plugin_name(plugin, rule);
308309
self.upsert_where(severity, |r| r.plugin_name() == plugin && r.name() == rule);
309310
}
310311
LintFilterKind::Generic(name) => self.upsert_where(severity, |r| r.name() == name),
@@ -317,6 +318,7 @@ impl ConfigStoreBuilder {
317318
self.rules.retain(|rule, _| rule.category() != *category);
318319
}
319320
LintFilterKind::Rule(plugin, rule) => {
321+
let (plugin, rule) = super::rules::unalias_plugin_name(plugin, rule);
320322
self.rules.retain(|r, _| r.plugin_name() != plugin || r.name() != rule);
321323
}
322324
LintFilterKind::Generic(name) => self.rules.retain(|rule, _| rule.name() != name),
@@ -857,6 +859,47 @@ mod test {
857859
assert_eq!(expected_plugins, builder.plugins());
858860
}
859861

862+
#[test]
863+
fn test_cli_rule_aliases() {
864+
let builder = ConfigStoreBuilder::default().and_builtin_plugins(LintPlugins::REACT, true);
865+
866+
// Assert rule doesn't exist by default
867+
assert_eq!(
868+
builder
869+
.rules
870+
.iter()
871+
.find(|(r, _)| r.plugin_name() == "react" && r.name() == "exhaustive-deps"),
872+
None
873+
);
874+
875+
let builder = builder.with_filter(
876+
&LintFilter::new(AllowWarnDeny::Deny, "react-hooks/exhaustive-deps").unwrap(),
877+
);
878+
879+
let (rule, sev) = builder
880+
.rules
881+
.iter()
882+
.find(|(r, _)| r.plugin_name() == "react" && r.name() == "exhaustive-deps")
883+
.expect("react/exhaustive-deps should be configured to Deny");
884+
885+
assert_eq!(rule.plugin_name(), "react");
886+
assert_eq!(rule.name(), "exhaustive-deps");
887+
assert_eq!(sev, &AllowWarnDeny::Deny);
888+
889+
let builder = builder.with_filter(
890+
&LintFilter::new(AllowWarnDeny::Allow, "react-hooks/exhaustive-deps").unwrap(),
891+
);
892+
893+
// Allowing the rule removes it from rules "overlay"
894+
assert_eq!(
895+
builder
896+
.rules
897+
.iter()
898+
.find(|(r, _)| r.plugin_name() == "react" && r.name() == "exhaustive-deps"),
899+
None
900+
);
901+
}
902+
860903
#[test]
861904
fn test_categories() {
862905
let oxlintrc: Oxlintrc = serde_json::from_str(

crates/oxc_linter/src/config/rules.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,10 @@ fn parse_rule_key(name: &str) -> (String, String) {
240240
name.to_string(),
241241
);
242242
};
243+
unalias_plugin_name(plugin_name, rule_name)
244+
}
243245

246+
pub(super) fn unalias_plugin_name(plugin_name: &str, rule_name: &str) -> (String, String) {
244247
let (oxlint_plugin_name, rule_name) = match plugin_name {
245248
"@typescript-eslint" => ("typescript", rule_name),
246249
// import-x has the same rules but better performance

0 commit comments

Comments
 (0)