Skip to content

Commit

Permalink
feat: enable checking all rules
Browse files Browse the repository at this point in the history
  • Loading branch information
AriPerkkio committed Feb 9, 2021
1 parent 9e9ad8a commit 9d1a299
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 44 deletions.
34 changes: 17 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,23 +74,23 @@ module.exports = {

#### Configuration options

| Name | Description                               | Type | Required | Default | Example |
| :-------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------- | :----------------- | :------------------------------------- | :------------------------------------------ |
| `repositories` | Repositories to scan in format of `owner/project` | `string[]` | :white_check_mark: | :x: | `['mui-org/material-ui', 'reach/reach-ui']` |
| `extensions` | Extensions of files under scanning | `string[]` | :white_check_mark: | :x: | `['js', 'jsx', 'ts', 'tsx']` |
| `eslintrc` | ESLint configuration | See [Configuring ESLint] | :white_check_mark: | :x: | `{ root: true, extends: ['eslint:all'] }` |
| `pathIgnorePattern` | Regexp pattern string used to exclude paths | `string` | :x: | :x: | `(node_modules\|docs\|\\/\\.git)` |
| `maxFileSizeBytes` | Max file size used to exclude bigger files | `number` | :x: | `2000000` | `1500000` |
| `rulesUnderTesting` | Array of rules used to filter out results. Use `undefined` or empty array when ESLint crashes are the only interest. | `string[]` | :x: | `[]` | `['no-empty', 'react/sort-prop-types']` |
| `resultParser` | Syntax for the result parser | `plaintext\|markdown` | :x: | `markdown` on CLI. `plaintext` on CI | `markdown` |
| `concurrentTasks` | Maximum amount of tasks run concurrently | `number` | :x: | `5` | `3` |
| `CI` | Flag used to set CI mode. `process.env.CI` is used when not set. | `boolean` | :x: | value of `process.env.CI === 'true'` | `true` |
| `logLevel` | Filter log messages based on their priority | `verbose\|info\|warn\|error` | :x: | `verbose` | `warn` |
| `cache` | Flag used to enable caching of cloned repositories. For CIs it's ideal to disable caching due to limited disk space. | `boolean` | :x: | `true` | `true` |
| `timeLimit` | Time limit before scan is interrupted and **exited successfully**. Ideal for avoiding CI timeouts in regression tests. | `number` | :x: | `5.5 * 60 * 60, // 5 hours 30 minutes` | `5 * 60 * 60 // 5 hours` |
| `compare` | Flag used to enable result comparison mode. Compares results of two scans and output the diff. Ideal for identifying new false positives when fixing existing rules. See [Fixing existing rules]. | `boolean` | :x: | `false` | `true` |
| `updateComparisonReference` | Flag used to enable result comparison reference updating. Indicates whether comparison base should be updated after scan has finished. Ideal to be turned off once initial comparison base has been collected. | `boolean` | :x: | `true` | `true` |
| `onComplete` | Callback invoked once scan is completed. Asynchronous functions are supported. Ideal for extending the process with custom features. | `(results, comparisonResults) => void`\|`Promise<void>`. See [onComplete example]. | :x: | :x: | `async (results, comparisonResults) => {}` |
| Name | Description&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Type | Required | Default | Example |
| :-------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------- | :----------------- | :------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------- |
| `repositories` | Repositories to scan in format of `owner/project` | `string[]` | :white_check_mark: | :x: | `['mui-org/material-ui', 'reach/reach-ui']` |
| `extensions` | Extensions of files under scanning | `string[]` | :white_check_mark: | :x: | `['js', 'jsx', 'ts', 'tsx']` |
| `eslintrc` | ESLint configuration | See [Configuring ESLint] | :white_check_mark: | :x: | `{ root: true, extends: ['eslint:all'] }` |
| `pathIgnorePattern` | Regexp pattern string used to exclude paths | `string` | :x: | :x: | `(node_modules\|docs\|\\/\\.git)` |
| `maxFileSizeBytes` | Max file size used to exclude bigger files | `number` | :x: | `2000000` | `1500000` |
| `rulesUnderTesting` | Array of rules or a filter method used to filter out results. Use `undefined` or empty array when ESLint crashes are the only interest. Filter method is called with `ruleId` and `options`. | `string[] \| (ruleId, { repository }) => boolean` | :x: | `[]` | `['no-empty', 'react/sort-prop-types']` `(ruleId, options) => ruleId === 'no-undef' && options.repository === 'owner/repo'` |
| `resultParser` | Syntax for the result parser | `plaintext\|markdown` | :x: | `markdown` on CLI. `plaintext` on CI | `markdown` |
| `concurrentTasks` | Maximum amount of tasks run concurrently | `number` | :x: | `5` | `3` |
| `CI` | Flag used to set CI mode. `process.env.CI` is used when not set. | `boolean` | :x: | value of `process.env.CI === 'true'` | `true` |
| `logLevel` | Filter log messages based on their priority | `verbose\|info\|warn\|error` | :x: | `verbose` | `warn` |
| `cache` | Flag used to enable caching of cloned repositories. For CIs it's ideal to disable caching due to limited disk space. | `boolean` | :x: | `true` | `true` |
| `timeLimit` | Time limit before scan is interrupted and **exited successfully**. Ideal for avoiding CI timeouts in regression tests. | `number` | :x: | `5.5 * 60 * 60, // 5 hours 30 minutes` | `5 * 60 * 60 // 5 hours` |
| `compare` | Flag used to enable result comparison mode. Compares results of two scans and output the diff. Ideal for identifying new false positives when fixing existing rules. See [Fixing existing rules]. | `boolean` | :x: | `false` | `true` |
| `updateComparisonReference` | Flag used to enable result comparison reference updating. Indicates whether comparison base should be updated after scan has finished. Ideal to be turned off once initial comparison base has been collected. | `boolean` | :x: | `true` | `true` |
| `onComplete` | Callback invoked once scan is completed. Asynchronous functions are supported. Ideal for extending the process with custom features. | `(results, comparisonResults) => void`\|`Promise<void>`. See [onComplete example]. | :x: | :x: | `async (results, comparisonResults) => {}` |

[configuring eslint]: https://eslint.org/docs/user-guide/configuring
[fixing existing rules]: #fixing-existing-rules
Expand Down
4 changes: 3 additions & 1 deletion lib/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ export interface Config {
extensions: string[];
pathIgnorePattern?: RegExp;
maxFileSizeBytes: number;
rulesUnderTesting: string[];
rulesUnderTesting:
| string[]
| ((ruleId: string, options: { repository: string }) => boolean);
resultParser: ResultParser;
concurrentTasks: number;
eslintrc: Linter.Config;
Expand Down
17 changes: 13 additions & 4 deletions lib/config/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,19 @@ export default async function validate(

// TODO nice-to-have: Validate rules match eslintrc config
// https://eslint.org/docs/developer-guide/nodejs-api#lintergetrules
if (rulesUnderTesting && rulesUnderTesting.length) {
errors.push(
validateStringArray('rulesUnderTesting', rulesUnderTesting)
);
if (rulesUnderTesting) {
if (Array.isArray(rulesUnderTesting)) {
// Empty rulesUnderTesting is valid
if (rulesUnderTesting.length) {
errors.push(
validateStringArray('rulesUnderTesting', rulesUnderTesting)
);
}
} else if (typeof rulesUnderTesting !== 'function') {
errors.push(
`rulesUnderTesting should be either an array or function.`
);
}
}

if (pathIgnorePattern) {
Expand Down
50 changes: 30 additions & 20 deletions lib/engine/worker-task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,27 +68,36 @@ async function executionTimeWarningWrapper<T>(
* Picks out messages which are under testing and constructs a small snippet of
* the erroneous code block
*/
function mergeMessagesWithSource(
all: Linter.LintMessage[],
result: ESLint.LintResult
): Linter.LintMessage[] {
const messages = result.messages.filter(
message =>
message.ruleId && config.rulesUnderTesting.includes(message.ruleId)
);

// Process only rules that are under testing
if (messages.length === 0) {
return all;
function getMessageReducer(repository: string) {
function messageFilter(message: Linter.LintMessage) {
if (!message.ruleId) return false;

if (typeof config.rulesUnderTesting === 'function') {
return config.rulesUnderTesting(message.ruleId, { repository });
}

return config.rulesUnderTesting.includes(message.ruleId);
}

return [
...all,
...messages.map(message => ({
...message,
source: constructCodeFrame(result.source, message),
})),
];
return function reducer(
all: Linter.LintMessage[],
result: ESLint.LintResult
): Linter.LintMessage[] {
const messages = result.messages.filter(messageFilter);

// Process only rules that are under testing
if (messages.length === 0) {
return all;
}

return [
...all,
...messages.map(message => ({
...message,
source: constructCodeFrame(result.source, message),
})),
];
};
}

/**
Expand Down Expand Up @@ -162,6 +171,7 @@ export default async function workerTask(): Promise<void> {
});

const { repository } = workerData as WorkerData;
const messageReducer = getMessageReducer(repository);

const files = await getFiles({
repository,
Expand Down Expand Up @@ -210,7 +220,7 @@ export default async function workerTask(): Promise<void> {
}

const messages = result
.reduce(mergeMessagesWithSource, [])
.reduce(messageReducer, [])
.filter(Boolean)
.map(message => ({ ...message, path }));

Expand Down
Loading

0 comments on commit 9d1a299

Please sign in to comment.