forked from mansona/lint-to-the-future-eslint
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
138 lines (111 loc) · 3.68 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
const { readFileSync, writeFileSync, lstatSync } = require('fs');
const { join } = require('path');
const importCwd = require('import-cwd');
const walkSync = require('walk-sync');
const semver = require('semver');
const fileGlobs = [
'*/app/**/*.js',
'*/addon/**/*.js',
'*/tests/**/*.js',
'*/app/**/*.ts',
'*/addon/**/*.ts',
'*/tests/**/*.ts',
];
function getIgnoreFile() {
let ignoreFile = ['**/node_modules/*'];
try {
ignoreFile = readFileSync(join(cwd, '.eslintignore'), 'utf8')
.split('\n')
.filter((line) => line.length)
.filter((line) => !line.startsWith('#'))
// walkSync can't handle these
.filter((line) => !line.startsWith('!'))
.map((line) => line.replace(/^\//, ''))
.map((line) => line.replace(/\/$/, '/*'));
} catch (e) {
// noop
}
return ignoreFile;
}
function ignoreError(error) {
const ruleIds = error.messages.map((message) => message.ruleId);
let uniqueIds = [...new Set(ruleIds)];
const file = readFileSync(error.filePath, 'utf8');
const firstLine = file.split('\n')[0];
// The whitespace after `eslint-disable` is important so `eslint-disable-next-line` and variants
// aren't picked up.
const matched = firstLine.match(/eslint-disable (.*)\*\//);
if (matched) {
const existing = matched[1].split(',').map((item) => item.trim());
uniqueIds = [...new Set([...ruleIds, ...existing])];
uniqueIds.sort((a, b) => a.localeCompare(b));
writeFileSync(error.filePath, file.replace(/^.*\n/, `/* eslint-disable ${uniqueIds.join(', ')} */\n`));
} else {
uniqueIds.sort((a, b) => a.localeCompare(b));
writeFileSync(error.filePath, `/* eslint-disable ${uniqueIds.join(', ')} */\n${file}`);
}
}
async function ignoreAll(cwd = process.cwd()) {
// eslint-disable-next-line global-require, import/no-dynamic-require
const currentPackageJSON = require(join(cwd, 'package.json'));
const eslintVersion = currentPackageJSON.devDependencies.eslint;
let cli;
let report;
let results;
const eslint = importCwd('eslint');
if (semver.intersects(eslintVersion, '8')) {
// this won't use the version in the repo but it will still use v8 because
// that is installed in this repo
const { ESLint } = eslint;
cli = new ESLint({
cwd,
errorOnUnmatchedPattern: false,
});
results = await cli.lintFiles(fileGlobs);
// remove warnings
results = ESLint.getErrorResults(results);
} else {
const { CLIEngine, ESLint } = eslint;
cli = new CLIEngine();
report = cli.executeOnFiles([cwd]);
results = report.results;
// remove warnings
results = ESLint.getErrorResults(results);
}
const errors = results.filter((result) => result.errorCount > 0);
errors.forEach(ignoreError);
}
function list(cwd = process.cwd()) {
const ignoreFile = getIgnoreFile();
const files = walkSync(cwd, {
globs: ['**/*.js', '**/*.ts'],
ignore: ignoreFile || ['**/node_modules/*'],
});
const output = {};
files.forEach((relativeFilePath) => {
const filePath = join(cwd, relativeFilePath);
// prevent odd times when directories might end with `.js` or `.ts`;
if (!lstatSync(filePath).isFile()) {
return;
}
const file = readFileSync(filePath, 'utf8');
const firstLine = file.split('\n')[0];
if (!firstLine.includes('eslint-disable ')) {
return;
}
const matched = firstLine.match(/eslint-disable (.*)\*\//);
const ignoreRules = matched[1].split(',').map((item) => item.trim());
ignoreRules.forEach((rule) => {
if (output[rule]) {
output[rule].push(filePath);
} else {
output[rule] = [filePath];
}
});
});
return output;
}
module.exports = {
ignoreAll,
list,
};