Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": ["jsx.json", "./typescript.json"],
"rules": {
"no-unused-vars": "off"
}
}
11 changes: 11 additions & 0 deletions apps/oxlint/fixtures/extends_config/overrides/jsx.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"plugins": ["jsx-a11y"],
"overrides": [
{
"files": ["*.{jsx,tsx}"],
"rules": {
"jsx-a11y/anchor-ambiguous-text": "error"
}
}
]
}
1 change: 1 addition & 0 deletions apps/oxlint/fixtures/extends_config/overrides/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
const x: any = 3;
3 changes: 3 additions & 0 deletions apps/oxlint/fixtures/extends_config/overrides/test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function component(): any {
return <a>click here</a>;
}
11 changes: 11 additions & 0 deletions apps/oxlint/fixtures/extends_config/overrides/typescript.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"overrides": [
{
"files": ["*.{ts,tsx}"],
"plugins": ["typescript"],
"rules": {
"@typescript-eslint/no-explicit-any": "error"
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"rules": {
"no-debugger": "error"
},
"overrides": [
{
"files": ["config/*.{ts,js}"],
"rules": { "no-debugger": "off" }
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": ["../.oxlintrc.json"],
"rules": { "no-debugger": "warn" } // This should take priority over the overrides in the parent config
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
debugger;
11 changes: 11 additions & 0 deletions apps/oxlint/src/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1029,4 +1029,15 @@ mod test {
let args = &["--config", "relative_paths/extends_extends_config.json", "console.js"];
Tester::new().with_cwd("fixtures/extends_config".into()).test_and_snapshot(args);
}

#[test]
fn test_extends_overrides() {
// Check that using a config with overrides works as expected
let args = &["--experimental-nested-config", "overrides"];
Tester::new().with_cwd("fixtures/extends_config".into()).test_and_snapshot(args);

// Check that using a config which extends a config with overrides works as expected
let args = &["--experimental-nested-config", "overrides_same_directory"];
Tester::new().with_cwd("fixtures/extends_config".into()).test_and_snapshot(args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
source: apps/oxlint/src/tester.rs
---
##########
arguments: --experimental-nested-config overrides
working directory: fixtures/extends_config
----------

x ]8;;https://oxc.rs/docs/guide/usage/linter/rules/typescript/no-explicit-any.html\typescript-eslint(no-explicit-any)]8;;\: Unexpected any. Specify a different type.
,-[overrides/test.ts:1:10]
1 | const x: any = 3;
: ^^^
`----
help: Use `unknown` instead, this will force you to explicitly, and safely, assert the type is correct.

x ]8;;https://oxc.rs/docs/guide/usage/linter/rules/typescript/no-explicit-any.html\typescript-eslint(no-explicit-any)]8;;\: Unexpected any. Specify a different type.
,-[overrides/test.tsx:1:23]
1 | function component(): any {
: ^^^
2 | return <a>click here</a>;
`----
help: Use `unknown` instead, this will force you to explicitly, and safely, assert the type is correct.

x ]8;;https://oxc.rs/docs/guide/usage/linter/rules/jsx_a11y/anchor-ambiguous-text.html\eslint-plugin-jsx-a11y(anchor-ambiguous-text)]8;;\: Unexpected ambagious anchor link text.
,-[overrides/test.tsx:2:10]
1 | function component(): any {
2 | return <a>click here</a>;
: ^^^^^^^^^^^^^^^^^
3 | }
`----

Found 0 warnings and 3 errors.
Finished in <variable>ms on 2 files with 100 rules using 1 threads.
----------
CLI result: LintFoundErrors
----------
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
source: apps/oxlint/src/tester.rs
---
##########
arguments: --experimental-nested-config overrides_same_directory
working directory: fixtures/extends_config
----------

! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html\eslint(no-debugger)]8;;\: `debugger` statement is not allowed
,-[overrides_same_directory/config/test.js:1:1]
1 | debugger;
: ^^^^^^^^^
`----
help: Delete this code.

Found 1 warning and 0 errors.
Finished in <variable>ms on 1 file with 100 rules using 1 threads.
----------
CLI result: LintSucceeded
----------
30 changes: 30 additions & 0 deletions apps/oxlint/src/snapshots/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
source: apps/oxlint/src/tester.rs
---
##########
arguments: overrides
working directory: fixtures/extends_config
----------

! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-unused-vars.html\eslint(no-unused-vars)]8;;\: Variable 'x' is declared but never used. Unused variables should start with a '_'.
,-[overrides/test.ts:1:7]
1 | const x: any = 3;
: |
: `-- 'x' is declared here
`----
help: Consider removing this declaration.

! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-unused-vars.html\eslint(no-unused-vars)]8;;\: Function 'component' is declared but never used.
,-[overrides/test.tsx:1:10]
1 | function component(): any {
: ^^^^|^^^^
: `-- 'component' is declared here
2 | return <a>click here</a>;
`----
help: Consider removing this declaration.

Found 2 warnings and 0 errors.
Finished in <variable>ms on 2 files with 100 rules using 1 threads.
----------
CLI result: LintSucceeded
----------
16 changes: 15 additions & 1 deletion crates/oxc_linter/src/config/config_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ use rustc_hash::FxHashSet;
use crate::{
AllowWarnDeny, LintConfig, LintFilter, LintFilterKind, Oxlintrc, RuleCategory, RuleEnum,
RuleWithSeverity,
config::{ConfigStore, ESLintRule, LintPlugins, OxlintOverrides, OxlintRules},
config::{
ConfigStore, ESLintRule, LintPlugins, OxlintOverrides, OxlintRules,
overrides::OxlintOverride,
},
rules::RULES,
};

Expand Down Expand Up @@ -135,6 +138,11 @@ impl ConfigStoreBuilder {
let rules = std::mem::take(&mut extended_config_store.rules);
builder = builder.with_rules(rules);
builder = builder.and_plugins(extended_config_store.plugins(), true);
if !extended_config_store.overrides.is_empty() {
let overrides =
std::mem::take(&mut extended_config_store.overrides);
builder = builder.with_overrides(overrides);
}
}
Err(err) => {
return Err(ConfigBuilderError::InvalidConfigFile {
Expand Down Expand Up @@ -201,6 +209,12 @@ impl ConfigStoreBuilder {
self
}

/// Appends an override to the end of the current list of overrides.
pub fn with_overrides<O: IntoIterator<Item = OxlintOverride>>(mut self, overrides: O) -> Self {
self.overrides.extend(overrides);
self
}

pub fn with_filters<I: IntoIterator<Item = LintFilter>>(mut self, filters: I) -> Self {
for filter in filters {
self = self.with_filter(filter);
Expand Down
21 changes: 20 additions & 1 deletion crates/oxc_linter/src/config/overrides.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use std::{borrow::Cow, ops::Deref, path::Path};
use std::{
borrow::Cow,
ops::{Deref, DerefMut},
path::Path,
};

use nonmax::NonMaxU32;
use schemars::{JsonSchema, r#gen, schema::Schema};
Expand Down Expand Up @@ -36,6 +40,21 @@ impl Deref for OxlintOverrides {
}
}

impl DerefMut for OxlintOverrides {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}

impl IntoIterator for OxlintOverrides {
type Item = OxlintOverride;
type IntoIter = <IndexVec<OverrideId, OxlintOverride> as IntoIterator>::IntoIter;

fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}

impl OxlintOverrides {
#[inline]
pub fn empty() -> Self {
Expand Down
Loading