Skip to content

Commit

Permalink
feat: support overrides in buildFromOxlintConfig/File)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sysix committed Nov 28, 2024
1 parent febb33a commit 7f90cb7
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 18 deletions.
54 changes: 52 additions & 2 deletions src/build-from-oxlint-config.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { describe, expect, it } from 'vitest';
import { assert, describe, expect, it } from 'vitest';
import {
buildFromOxlintConfig,
buildFromOxlintConfigFile,
Expand Down Expand Up @@ -184,8 +184,58 @@ describe('buildFromOxlintConfig', () => {
expect('unknown' in configs[0].rules!).toBe(false);
expect('@next/next/no-img-element' in configs[0].rules!).toBe(false);
});
});

describe('overrides', () => {
it('supports simple files + rules overrides', () => {
const configs = buildFromOxlintConfig({
rules: {
eqeqeq: 'warn',
},
overrides: [
{
files: ['./*.ts'],
rules: {
'no-alert': 'error',
},
},
],
});

expect(configs.length).toBe(2);
assert(configs[0].rules !== undefined);
expect('eqeqeq' in configs[0].rules).toBe(true);
expect('no-alert' in configs[0].rules).toBe(false);

assert(configs[1].rules !== undefined);
expect('eqeqeq' in configs[1].rules).toBe(false);
expect('no-alert' in configs[1].rules).toBe(true);
});

it('supports simple files + plugins overrides', () => {
const configs = buildFromOxlintConfig({
rules: {
eqeqeq: 'warn',
},
overrides: [
{
files: ['./*.test.ts'],
plugins: ['vitest'],
},
],
});

expect(configs.length).toBe(2);
assert(configs[0].rules !== undefined);
expect('eqeqeq' in configs[0].rules).toBe(true);
expect('vitest/no-conditional-tests' in configs[0].rules).toBe(false);

console.log(configs[1].rules);
assert(configs[1].rules !== undefined);
expect('eqeqeq' in configs[1].rules).toBe(false);
expect('vitest/no-conditional-tests' in configs[1].rules).toBe(true);
});
});
});
const createConfigFileAndBuildFromIt = (
filename: string,
content: string
Expand Down
35 changes: 19 additions & 16 deletions src/build-from-oxlint-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ type OxlintConfigCategories = Record<string, unknown>;
type OxlintConfigRules = Record<string, unknown>;

type OxlintConfigOverride = {
files?: string[];
files: string[];
plugins?: OxlintConfigPlugins;
rules?: OxlintConfigRules;
};

Expand Down Expand Up @@ -183,25 +184,30 @@ const handleRulesScope = (

const handleOverridesScope = (
overrides: OxlintConfigOverride[],
configs: EslintPluginOxLintConfig[]
configs: EslintPluginOxLintConfig[],
baseCategories?: OxlintConfigCategories
): void => {
for (const overrideIndex in overrides) {
const override = overrides[overrideIndex];
const eslintRules: Record<string, 'off'> = {};
const eslintConfig: EslintPluginOxLintConfig = {
name: `oxlint/from-oxlint-config-override-${overrideIndex}`,
};

// expect that oxlint `files` syntax is the same as eslint
if ('files' in override) {
eslintConfig.files = override.files;
eslintConfig.files = override.files;

const plugins = readPluginsFromConfig(override);
if (baseCategories !== undefined && plugins !== undefined) {
handleCategoriesScope(plugins, baseCategories, eslintRules);
}

if (isObject(override.rules)) {
const rules: Record<string, 'off'> = {};
handleRulesScope(override.rules!, rules);
eslintConfig.rules = rules;
const rules = readRulesFromConfig(override);
if (rules !== undefined) {
handleRulesScope(rules, eslintRules);
}

eslintConfig.rules = eslintRules;
configs.push(eslintConfig);
}
};
Expand Down Expand Up @@ -229,7 +235,7 @@ const isActiveValue = (value: unknown) =>
* it returns `undefined` when not found or invalid.
*/
const readPluginsFromConfig = (
config: OxlintConfig
config: OxlintConfig | OxlintConfigOverride
): OxlintConfigPlugins | undefined => {
return 'plugins' in config && Array.isArray(config.plugins)
? (config.plugins as OxlintConfigPlugins)
Expand All @@ -253,7 +259,7 @@ const readCategoriesFromConfig = (
* it returns `undefined` when not found or invalid.
*/
const readRulesFromConfig = (
config: OxlintConfig
config: OxlintConfig | OxlintConfigOverride
): OxlintConfigRules | undefined => {
return 'rules' in config && isObject(config.rules)
? (config.rules as OxlintConfigRules)
Expand All @@ -277,6 +283,7 @@ export const buildFromOxlintConfig = (
): EslintPluginOxLintConfig[] => {
const rules: Record<string, 'off'> = {};
const plugins = readPluginsFromConfig(config) ?? defaultPlugins;
const categories = readCategoriesFromConfig(config) ?? defaultCategories;

// it is not a plugin but it is activated by default
plugins.push('eslint');
Expand All @@ -287,11 +294,7 @@ export const buildFromOxlintConfig = (
plugins.push('react-hooks');
}

handleCategoriesScope(
plugins,
readCategoriesFromConfig(config) ?? defaultCategories,
rules
);
handleCategoriesScope(plugins, categories, rules);

const configRules = readRulesFromConfig(config);

Expand All @@ -308,7 +311,7 @@ export const buildFromOxlintConfig = (
];

if (overrides !== undefined) {
handleOverridesScope(overrides, configs);
handleOverridesScope(overrides, configs, categories);
}

return configs;
Expand Down

0 comments on commit 7f90cb7

Please sign in to comment.