mirror of
https://github.com/renovatebot/renovate.git
synced 2026-11-01 02:00:10 +00:00
a473e73b3e
Adds a custom oxlint rule renovate/v8-ignore-no-count that flags the count form '/* v8 ignore next <N> */'. The count is not honored by vitest's ast-v8-to-istanbul hint parser, which captures only the keyword (if/else/next/file); 'next' always exempts exactly the next AST node. Trailing counts therefore suggest a line range that is never applied and mislead readers. The rule is autofixable (drops the count, preserving actual behavior) and has been applied to all existing occurrences.
65 lines
2.1 KiB
TypeScript
65 lines
2.1 KiB
TypeScript
import { defineRule } from '@oxlint/plugins';
|
|
|
|
/**
|
|
* Note on the `next <N>` count form of these coverage-ignore hints:
|
|
* empirically verified against vitest 4 (`@vitest/coverage-v8` with
|
|
* `ast-v8-to-istanbul`) that the count `N` is NOT honored — the hint parser
|
|
* only captures the keyword (`if`/`else`/`next`/`file`) and `next` always
|
|
* exempts exactly the next AST node, however many lines it spans: `next 2`
|
|
* before two sibling statements exempts only the first, while `next 1`
|
|
* before a multi-line `if` block exempts the whole block. This rule only
|
|
* requires a justification; the count form itself is forbidden by the
|
|
* companion `v8-ignore-no-count` rule.
|
|
*
|
|
* A `stop` marker only terminates a region opened by `start`; the
|
|
* justification lives on the `start` marker, so bare stops are exempt.
|
|
*/
|
|
const bareStopRegex = /^\s*v8 ignore stop\s*$/;
|
|
|
|
/**
|
|
* `--` (or `---`) separator followed by a non-empty reason,
|
|
* e.g. `v8 ignore next -- should never happen`.
|
|
*/
|
|
const dashReasonRegex = /v8 ignore.*?--+\s+\S/;
|
|
|
|
/**
|
|
* Legacy colon form, e.g. `v8 ignore next: hard to test`. Accepted because
|
|
* it is widespread in the codebase, but the dash form is recommended.
|
|
*/
|
|
const colonReasonRegex = /v8 ignore\s+[a-z]+(?:\s+\d+)?\s*:\s*\S/;
|
|
|
|
export default defineRule({
|
|
meta: {
|
|
type: 'problem',
|
|
messages: {
|
|
missingReason:
|
|
'Coverage-ignore comments must carry a justification: /* v8 ignore <kind> -- <reason> */',
|
|
},
|
|
},
|
|
createOnce(context) {
|
|
return {
|
|
Program() {
|
|
for (const comment of context.sourceCode.getAllComments()) {
|
|
const text = comment.value;
|
|
if (!text.includes('v8 ignore')) {
|
|
continue;
|
|
}
|
|
if (bareStopRegex.test(text)) {
|
|
continue;
|
|
}
|
|
if (dashReasonRegex.test(text) || colonReasonRegex.test(text)) {
|
|
continue;
|
|
}
|
|
if (!comment.loc) {
|
|
continue;
|
|
}
|
|
context.report({
|
|
loc: comment.loc,
|
|
messageId: 'missingReason',
|
|
});
|
|
}
|
|
},
|
|
};
|
|
},
|
|
});
|