Chore: Move betterer eslint rules to use eslint suppressions (#106267)
Co-authored-by: joshhunt <josh.hunt@grafana.com>
This commit is contained in:
co-authored by
joshhunt
parent
df685757ff
commit
55b638ea98
@@ -32,6 +32,17 @@ do
|
||||
BETTERER_STATS+="\"grafana.ci-code.betterer.${name}\": \"${value}\","
|
||||
done <<< "$(yarn betterer:stats)"
|
||||
|
||||
ESLINT_STATS=""
|
||||
yarn lint:ts --format ./scripts/cli/eslint-stats-reporter.mjs -o eslint-stats.txt
|
||||
while read -r name value
|
||||
do
|
||||
ESLINT_STATS+=$'\n '
|
||||
# We still report these as "betterer" as the dashboards/other scripts will still look for it there
|
||||
ESLINT_STATS+="\"grafana.ci-code.betterer.${name}\": \"${value}\","
|
||||
done <<< "$(cat eslint-stats.txt)"
|
||||
|
||||
rm eslint-stats.txt
|
||||
|
||||
I18N_STATS=""
|
||||
while read -r name value
|
||||
do
|
||||
@@ -49,6 +60,7 @@ done <<< "$(yarn themes:usage | awk '$4 == "@grafana/theme-token-usage" {print $
|
||||
echo "Metrics: {
|
||||
$THEME_TOKEN_USAGE
|
||||
$BETTERER_STATS
|
||||
$ESLINT_STATS
|
||||
$I18N_STATS
|
||||
\"grafana.ci-code.strictErrors\": \"${ERROR_COUNT}\",
|
||||
\"grafana.ci-code.accessibilityErrors\": \"${ACCESSIBILITY_ERRORS}\",
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
//@ts-check
|
||||
import lodash from 'lodash';
|
||||
const { camelCase } = lodash;
|
||||
|
||||
/**
|
||||
* Rule IDs that are overly verbose and that we want to combine so they report more cleanly
|
||||
*
|
||||
* i.e. so we can report `reactHooksRulesOfHooks` instead of `reactHookFooIsCalledConditionallyReactHooksMust...`
|
||||
*/
|
||||
const rulesToCombine = ['react-hooks/rules-of-hooks', 'react/no-unescaped-entities', 'no-barrel-files/no-barrel-files'];
|
||||
|
||||
const legacyChecksToTransform = [
|
||||
{ messageRegex: /gfFormUsage/i, prefix: 'noGfFormUsage' },
|
||||
{ messageRegex: /skippingA11Y/i, prefix: 'noSkippingA11YTestsInStories' },
|
||||
];
|
||||
|
||||
/**
|
||||
* Custom formatter that outputs suppressed rule violations in a format suitable for
|
||||
* consuming on our CI code stats scripts
|
||||
*
|
||||
* Output in the format:
|
||||
* @example
|
||||
* betterEslint_reactHooksRulesOfHooks 123
|
||||
* betterEslint_noBarrelFilesNoBarrelFiles 123
|
||||
*
|
||||
* @type {import('eslint').ESLint.FormatterFunction}
|
||||
*/
|
||||
export default function statsReporter(results) {
|
||||
/** @type {Record<string, number>} */
|
||||
const countByMessage = {};
|
||||
|
||||
for (const result of results) {
|
||||
for (const message of result.suppressedMessages) {
|
||||
// eslint disable directives count as suppressions
|
||||
// we only want to report the case where everything is a file suppression
|
||||
const everySuppressionIsFile = message.suppressions.every((suppression) => suppression.kind === 'file');
|
||||
|
||||
if (!everySuppressionIsFile) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const key =
|
||||
message.ruleId && rulesToCombine.includes(message.ruleId)
|
||||
? camelCase(message.ruleId)
|
||||
: camelCase(message.message);
|
||||
countByMessage[key] = (countByMessage[key] || 0) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return Object.entries(countByMessage)
|
||||
.map(([key, value]) => {
|
||||
const prefix = legacyChecksToTransform.find((v) => v.messageRegex.test(key))?.prefix || 'betterEslint';
|
||||
return `${prefix}_${key} ${value}`;
|
||||
})
|
||||
.join('\n');
|
||||
}
|
||||
@@ -10,5 +10,6 @@
|
||||
"compilerOptions": {
|
||||
"module": "commonjs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"include": ["./**/*.ts", "./**/*.mts", "./**/*.js", "./**/*.mjs"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user