Skip to content

Commit

Permalink
fix!: ignore nursery rules (#256)
Browse files Browse the repository at this point in the history
**BREAKING CHANGE:** The Configuration `oxlint.configs['flat/nursery']`
does not exist anymore.
The function `buildFromOxlint` will also ignore this category from now
on.
  • Loading branch information
Sysix authored Nov 22, 2024
1 parent bf7f215 commit a7f8847
Show file tree
Hide file tree
Showing 10 changed files with 60 additions and 128 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ And then you can add the following script to your `package.json`:

// turn eslint rules off by oxlint category
'flat/pedantic': { rules: [Object] },
'flat/nursery': { rules: [Object] },
'flat/style': { rules: [Object] },
'flat/correctness': { rules: [Object] },
'flat/restriction': { rules: [Object] },
Expand Down
3 changes: 3 additions & 0 deletions scripts/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ export const SPARSE_CLONE_DIRECTORY = 'crates/oxc_linter/src';
// these are the rules that don't have a direct equivalent in the eslint rules
export const ignoreScope = new Set(['oxc', 'deepscan', 'security']);

// these are the rules that are not fully implemented in oxc
export const ignoreCategories = new Set(['nursery']);

export function convertScope(scope: string) {
return Reflect.has(aliasPluginNames, scope)
? aliasPluginNames[scope as 'eslint']
Expand Down
68 changes: 39 additions & 29 deletions scripts/traverse-rules.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { promises } from 'node:fs';
import path from 'node:path';
import {
ignoreCategories,
ignoreScope,
prefixScope,
SPARSE_CLONE_DIRECTORY,
Expand Down Expand Up @@ -70,13 +71,6 @@ async function processFile(
): Promise<void> {
const content = await promises.readFile(filePath, 'utf8');

// find the correct macro block where `);` or `}` is the end of the block
// ensure that the `);` or `}` is on its own line, with no characters before it
const blockRegex =
/declare_oxc_lint!\s*(\(([\S\s]*?)^\s*\)\s*;?|\s*{([\S\s]*?)^\s*}\s)/gm;

let match = blockRegex.exec(content);

// 'ok' way to get the scope, depends on the directory structure
let scope = getFolderNameUnderRules(filePath);
const shouldIgnoreRule = ignoreScope.has(scope);
Expand Down Expand Up @@ -111,16 +105,24 @@ async function processFile(
return;
}

// find the correct macro block where `);` or `}` is the end of the block
// ensure that the `);` or `}` is on its own line, with no characters before it
const blockRegex =
/declare_oxc_lint!\s*(\(([\S\s]*?)^\s*\)\s*;?|\s*{([\S\s]*?)^\s*}\s)/gm;

let match = blockRegex.exec(content);

if (match === null) {
failureResultArray.push({
value: effectiveRuleName,
scope: scope,
category: 'unknown',
error: 'No match block for `declare_oxc_lint`',
});
return;
}

while (match !== null) {
do {
const block = match[2] ?? match[3];

// Remove comments to prevent them from affecting the regex
Expand All @@ -134,35 +136,43 @@ async function processFile(
const keywordRegex = /,\s*(\w+)\s*,?\s*(?:(\w+)\s*,?\s*)?$/;
const keywordMatch = keywordRegex.exec(cleanBlock);

if (keywordMatch) {
successResultArray.push({
value: effectiveRuleName,
scope: scope,
category: keywordMatch[1],
});

if (scope === 'eslint') {
const ruleName = effectiveRuleName.replace(/^.*\//, '');

if (typescriptRulesExtendEslintRules.includes(ruleName)) {
successResultArray.push({
value: `@typescript-eslint/${ruleName}`,
scope: 'typescript',
category: keywordMatch[1],
});
}
}
} else {
if (!keywordMatch) {
failureResultArray.push({
value: effectiveRuleName,
scope: `unknown: ${scope}`,
category: 'unknown',
error: 'Could not extract keyword from macro block',
});
continue;
}

match = blockRegex.exec(content); // Update match for the next iteration
}
if (ignoreCategories.has(keywordMatch[1])) {
skippedResultArray.push({
value: effectiveRuleName,
scope: scope,
category: keywordMatch[1],
});
continue;
}

successResultArray.push({
value: effectiveRuleName,
scope: scope,
category: keywordMatch[1],
});

if (scope === 'eslint') {
const ruleName = effectiveRuleName.replace(/^.*\//, '');

if (typescriptRulesExtendEslintRules.includes(ruleName)) {
successResultArray.push({
value: `@typescript-eslint/${ruleName}`,
scope: 'typescript',
category: keywordMatch[1],
});
}
}
} while ((match = blockRegex.exec(content)));
}

export function getFolderNameUnderRules(filePath: string) {
Expand Down
16 changes: 9 additions & 7 deletions src/__snapshots__/build-from-oxlint-config.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ exports[`buildFromOxlintConfig > custom plugins, custom categories > customPlugi
{
"name": "oxlint/from-oxlint-config",
"rules": {
"constructor-super": "off",
"getter-return": "off",
"import/export": "off",
"import/no-deprecated": "off",
"import/no-unused-modules": "off",
"no-undef": "off",
"no-unreachable": "off",
"import/no-duplicates": "off",
"import/no-named-as-default": "off",
"import/no-named-as-default-member": "off",
"import/no-self-import": "off",
"no-extend-native": "off",
"no-new": "off",
"no-unexpected-multiline": "off",
"no-useless-concat": "off",
"no-useless-constructor": "off",
},
},
]
Expand Down
38 changes: 0 additions & 38 deletions src/__snapshots__/configs.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,6 @@ exports[`contains all the oxlint rules 1`] = `
"@typescript-eslint/consistent-type-definitions": [
0,
],
"@typescript-eslint/consistent-type-imports": [
0,
],
"@typescript-eslint/default-param-last": [
0,
],
Expand Down Expand Up @@ -217,9 +214,6 @@ exports[`contains all the oxlint rules 1`] = `
"checkForEach": false,
},
],
"constructor-super": [
0,
],
"default-case": [
0,
{},
Expand All @@ -241,19 +235,12 @@ exports[`contains all the oxlint rules 1`] = `
"always",
{},
],
"getter-return": [
0,
{},
],
"guard-for-in": [
0,
],
"import/default": [
0,
],
"import/export": [
0,
],
"import/first": [
0,
],
Expand Down Expand Up @@ -281,9 +268,6 @@ exports[`contains all the oxlint rules 1`] = `
"import/no-default-export": [
0,
],
"import/no-deprecated": [
0,
],
"import/no-duplicates": [
0,
],
Expand All @@ -299,9 +283,6 @@ exports[`contains all the oxlint rules 1`] = `
"import/no-self-import": [
0,
],
"import/no-unused-modules": [
0,
],
"import/no-webpack-loader-syntax": [
0,
],
Expand Down Expand Up @@ -853,19 +834,12 @@ exports[`contains all the oxlint rules 1`] = `
"no-throw-literal": [
0,
],
"no-undef": [
0,
{},
],
"no-undefined": [
0,
],
"no-unexpected-multiline": [
0,
],
"no-unreachable": [
0,
],
"no-unsafe-finally": [
0,
],
Expand Down Expand Up @@ -939,9 +913,6 @@ exports[`contains all the oxlint rules 1`] = `
"promise/no-new-statics": [
0,
],
"promise/no-return-in-finally": [
0,
],
"promise/param-names": [
0,
],
Expand All @@ -961,12 +932,6 @@ exports[`contains all the oxlint rules 1`] = `
0,
"always",
],
"react-hooks/exhaustive-deps": [
0,
],
"react-hooks/rules-of-hooks": [
0,
],
"react-perf/jsx-no-jsx-as-prop": [
0,
],
Expand Down Expand Up @@ -1057,9 +1022,6 @@ exports[`contains all the oxlint rules 1`] = `
"react/react-in-jsx-scope": [
0,
],
"react/require-render-return": [
0,
],
"react/self-closing-comp": [
0,
],
Expand Down
18 changes: 9 additions & 9 deletions src/build-from-oxlint-config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ describe('buildFromOxlintConfig', () => {
buildFromOxlintConfig({
plugins: ['import'],
categories: {
nursery: 'warn',
suspicious: 'warn',
correctness: 'off',
},
})
Expand All @@ -112,17 +112,17 @@ describe('buildFromOxlintConfig', () => {
const configs = buildFromOxlintConfig({
plugins: ['import'],
categories: {
nursery: 'warn',
suspicious: 'warn',
correctness: 'off',
},
rules: {
'import/no-unused-modules': 'off',
'import/no-self-import': 'off',
},
});

expect(configs.length).toBe(1);
expect(configs[0].rules).not.toBeUndefined();
expect('import/no-unused-modules' in configs[0].rules!).toBe(false);
expect('import/no-self-import' in configs[0].rules!).toBe(false);
});

// look here: <https://github.com/oxc-project/oxc/blob/0b329516372a0353e9eb18e5bc0fbe63bce21fee/crates/oxc_linter/src/config/rules.rs#L285>
Expand All @@ -134,7 +134,7 @@ describe('buildFromOxlintConfig', () => {
'react_perf/jsx-no-new-array-as-prop': 'warn',
'nextjs/no-img-element': 'warn',
'jsx_a11y/alt-text': 'warn',
'react/rules-of-hooks': 'warn',
// 'react/rules-of-hooks': 'warn', -- rules are currently in nursery
// 'deepscan/xxx': 'warn',
},
});
Expand All @@ -148,7 +148,7 @@ describe('buildFromOxlintConfig', () => {
);
expect('@next/next/no-img-element' in configs[0].rules!).toBe(true);
expect('jsx-a11y/alt-text' in configs[0].rules!).toBe(true);
expect('react-hooks/rules-of-hooks' in configs[0].rules!).toBe(true);
// expect('react-hooks/rules-of-hooks' in configs[0].rules!).toBe(true); -- rules are currently in nursery
});

it('detects rules without plugin name', () => {
Expand Down Expand Up @@ -307,7 +307,7 @@ describe('integration test with oxlint', () => {
{ plugins: ['vite'], rules: { eqeqeq: 'off' } },

// categories change
{ categories: { correctness: 'off', nusery: 'warn' } },
{ categories: { correctness: 'off', suspicious: 'warn' } },
// combination plugin + categires + rules
{
plugins: ['vite'],
Expand All @@ -317,8 +317,8 @@ describe('integration test with oxlint', () => {
// all categories enabled
{
categories: {
nursery: 'off', // we not support this category
correctness: 'warn',
nursery: 'warn',
pedantic: 'warn',
perf: 'warn',
restriction: 'warn',
Expand Down Expand Up @@ -360,8 +360,8 @@ describe('integration test with oxlint', () => {
'vitest',
],
categories: {
nursery: 'off', // we not support this category
correctness: 'warn',
nursery: 'off', // ToDo: something with the import plugin
pedantic: 'warn',
perf: 'warn',
restriction: 'warn',
Expand Down
6 changes: 0 additions & 6 deletions src/generated/configs-by-category.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@ const pedanticConfig = {
rules: rules.pedanticRules,
};

const nurseryConfig = {
name: 'oxlint/nursery',
rules: rules.nurseryRules,
};

const restrictionConfig = {
name: 'oxlint/restriction',
rules: rules.restrictionRules,
Expand Down Expand Up @@ -39,7 +34,6 @@ const suspiciousConfig = {

const configByCategory = {
'flat/pedantic': pedanticConfig,
'flat/nursery': nurseryConfig,
'flat/restriction': restrictionConfig,
'flat/style': styleConfig,
'flat/correctness': correctnessConfig,
Expand Down
6 changes: 0 additions & 6 deletions src/generated/configs-by-scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,6 @@ const reactConfig = {
rules: rules.reactRules,
};

const reactHooksConfig = {
name: 'oxlint/react-hooks',
rules: rules.reactHooksRules,
};

const reactPerfConfig = {
name: 'oxlint/react-perf',
rules: rules.reactPerfRules,
Expand Down Expand Up @@ -82,7 +77,6 @@ const configByScope = {
'flat/node': nodeConfig,
'flat/promise': promiseConfig,
'flat/react': reactConfig,
'flat/react-hooks': reactHooksConfig,
'flat/react-perf': reactPerfConfig,
'flat/typescript': typescriptConfig,
'flat/unicorn': unicornConfig,
Expand Down
Loading

0 comments on commit a7f8847

Please sign in to comment.