Chore: Refactor betterer eslint to use overrides (#88442)

* Chore: Refactor betterer eslint to use overrides

* more comments
This commit is contained in:
Josh Hunt
2024-05-30 10:09:30 +01:00
committed by GitHub
parent 650f291054
commit 5190e68ab1
+44 -75
View File
@@ -75,11 +75,17 @@ function regexp(pattern: RegExp, issueMessage: string) {
function countEslintErrors() { function countEslintErrors() {
return new BettererFileTest(async (filePaths, fileTestResult, resolver) => { return new BettererFileTest(async (filePaths, fileTestResult, resolver) => {
// Just bail early if there's no files to test. Prevents trying to get the base config from failing
if (filePaths.length === 0) {
return;
}
const { baseDirectory } = resolver; const { baseDirectory } = resolver;
const cli = new ESLint({ cwd: baseDirectory }); const cli = new ESLint({ cwd: baseDirectory });
const eslintConfigFiles = await glob('**/.eslintrc'); // Get the base config to set up parsing etc correctly
const eslintConfigMainPaths = eslintConfigFiles.map((file) => path.resolve(path.dirname(file))); // this is by far the slowest part of this code. It takes eslint about 2 seconds just to find the config
const baseConfig = await cli.calculateConfigForFile(filePaths[0]);
const baseRules: Partial<Linter.RulesRecord> = { const baseRules: Partial<Linter.RulesRecord> = {
'@emotion/syntax-preference': [2, 'object'], '@emotion/syntax-preference': [2, 'object'],
@@ -99,81 +105,44 @@ function countEslintErrors() {
], ],
}; };
const nonTestFilesRules: Partial<Linter.RulesRecord> = { const config: Linter.Config = {
...baseRules, ...baseConfig,
'@typescript-eslint/consistent-type-assertions': ['error', { assertionStyle: 'never' }], rules: baseRules,
};
const grafanaRules: Partial<Linter.RulesRecord> = { // Be careful when specifying overrides for the same rules as in baseRules - it will... override
...nonTestFilesRules, // the same rule, not merge them with different configurations
'no-barrel-files/no-barrel-files': 'error', overrides: [
}; {
files: ['**/*.{ts,tsx}'],
const testFilesAndGrafanaRules: Partial<Linter.RulesRecord> = { excludedFiles: ['*.{test,spec}.{ts,tsx}', '**/__mocks__/**', '**/public/test/**'],
...baseRules, rules: {
'no-barrel-files/no-barrel-files': 'error', '@typescript-eslint/consistent-type-assertions': ['error', { assertionStyle: 'never' }],
}; },
// group files by eslint config file
// this will create two file groups for each eslint config file
// one for test files and one for non-test files
const fileGroups: Record<string, string[]> = {};
for (const filePath of filePaths) {
let configPath = eslintConfigMainPaths.find((configPath) => filePath.startsWith(configPath)) ?? '';
const isTestFile =
filePath.endsWith('.test.tsx') ||
filePath.endsWith('.test.ts') ||
filePath.includes('__mocks__') ||
filePath.includes('public/test/');
const isGrafanaFile = filePath.includes('public/app/');
if (isGrafanaFile && isTestFile) {
configPath += '-test-grafana';
} else if (isGrafanaFile) {
configPath += '-grafana';
} else if (isTestFile) {
configPath += '-test';
}
if (!fileGroups[configPath]) {
fileGroups[configPath] = [];
}
fileGroups[configPath].push(filePath);
}
for (const configPath of Object.keys(fileGroups)) {
let rules;
if (configPath.endsWith('-test-grafana')) {
rules = testFilesAndGrafanaRules;
} else if (configPath.endsWith('-test')) {
rules = baseRules;
} else if (configPath.endsWith('-grafana')) {
rules = grafanaRules;
} else {
rules = nonTestFilesRules;
}
// this is by far the slowest part of this code. It takes eslint about 2 seconds just to find the config
const linterOptions = (await cli.calculateConfigForFile(fileGroups[configPath][0])) as Linter.Config;
const runner = new ESLint({
baseConfig: {
...linterOptions,
rules: rules,
}, },
useEslintrc: false,
cwd: baseDirectory, {
}); files: ['public/app/**/*.{ts,tsx}'],
const lintResults = await runner.lintFiles(fileGroups[configPath]); rules: {
lintResults 'no-barrel-files/no-barrel-files': 'error',
.filter((lintResult) => lintResult.source) },
.forEach((lintResult) => { },
const { messages } = lintResult; ],
const filePath = lintResult.filePath; };
const file = fileTestResult.addFile(filePath, '');
messages.forEach((message, index) => { const runner = new ESLint({
file.addIssue(0, 0, message.message, `${index}`); baseConfig: config,
}); useEslintrc: false,
cwd: baseDirectory,
});
const lintResults = await runner.lintFiles(Array.from(filePaths));
lintResults
.filter((lintResult) => lintResult.source)
.forEach(({ messages, filePath }) => {
const file = fileTestResult.addFile(filePath, '');
messages.forEach((message, index) => {
file.addIssue(0, 0, message.message, `${index}`);
}); });
} });
}); });
} }