-
-
Notifications
You must be signed in to change notification settings - Fork 290
/
index.js
129 lines (103 loc) · 3.35 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
import path from 'node:path';
import {ESLint} from 'eslint';
import {globby, isGitIgnoredSync} from 'globby';
import {isEqual} from 'lodash-es';
import micromatch from 'micromatch';
import arrify from 'arrify';
import slash from 'slash';
import {
parseOptions,
getIgnores,
mergeWithFileConfig,
getOptionGroups,
} from './lib/options-manager.js';
import {mergeReports, processReport, getIgnoredReport} from './lib/report.js';
const globFiles = async (patterns, options) => {
const {
options: {
ignores,
extensions,
cwd,
},
} = await mergeWithFileConfig(options);
patterns = patterns.length === 0
? [`**/*.{${extensions.join(',')}}`]
: arrify(patterns).map(pattern => slash(pattern));
const files = await globby(
patterns,
{
ignore: ignores, gitignore: true, absolute: true, cwd,
},
);
return files.filter(file => extensions.includes(path.extname(file).slice(1)));
};
const getConfig = async options => {
const {filePath, eslintOptions} = await parseOptions(options);
const engine = new ESLint(eslintOptions);
return engine.calculateConfigForFile(filePath);
};
const lintText = async (string, options) => {
const [[options_]] = Object.values(await getOptionGroups([options && options.filePath], options));
const {filePath, warnIgnored, eslintOptions, isQuiet} = options_;
const {cwd, baseConfig: {ignorePatterns}} = eslintOptions;
if (typeof filePath !== 'string' && !isEqual(getIgnores({}), ignorePatterns)) {
throw new Error('The `ignores` option requires the `filePath` option to be defined.');
}
if (
filePath
&& (
micromatch.isMatch(path.relative(cwd, filePath), ignorePatterns)
|| isGitIgnoredSync({cwd})(filePath)
)
) {
return getIgnoredReport(filePath);
}
const eslint = new ESLint(eslintOptions);
if (filePath && await eslint.isPathIgnored(filePath)) {
return getIgnoredReport(filePath);
}
const report = await eslint.lintText(string, {filePath, warnIgnored});
const rulesMeta = eslint.getRulesMetaForResults(report);
return processReport(report, {isQuiet, rulesMeta});
};
const lintFiles = async (patterns, options) => {
const files = await globFiles(patterns, options);
const groups = await getOptionGroups(files, options);
const reports = await Promise.all(
Object.values(groups)
.map(async filesWithOptions => {
const options = filesWithOptions[0];
const eslint = new ESLint(options.eslintOptions);
const files = [];
for (const options of filesWithOptions) {
const {filePath, eslintOptions} = options;
const {cwd, baseConfig: {ignorePatterns}} = eslintOptions;
if (
micromatch.isMatch(path.relative(cwd, filePath), ignorePatterns)
// eslint-disable-next-line no-await-in-loop -- Not worth refactoring
|| await eslint.isPathIgnored(filePath)
) {
continue;
}
files.push(filePath);
}
const report = await eslint.lintFiles(files);
const rulesMeta = eslint.getRulesMetaForResults(report);
return processReport(report, {isQuiet: options.isQuiet, rulesMeta});
}));
const report = mergeReports(reports);
return report;
};
const getFormatter = async name => {
const {format} = await new ESLint().loadFormatter(name);
return format;
};
const xo = {
getFormatter,
getErrorResults: ESLint.getErrorResults,
outputFixes: async ({results}) => ESLint.outputFixes(results),
getConfig,
lintText,
lintFiles,
};
export default xo;