-
Notifications
You must be signed in to change notification settings - Fork 38
/
Copy pathrule-finder.js
148 lines (120 loc) · 4.9 KB
/
rule-finder.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
139
140
141
142
143
144
145
146
147
148
const path = require('path');
const eslint = require('eslint');
const glob = require('glob');
const isAbsolute = require('path-is-absolute');
const difference = require('./array-diff');
const getSortedRules = require('./sort-rules');
const normalizePluginName = require('./normalize-plugin-name');
function _getConfigFile(specifiedFile) {
if (specifiedFile) {
if (isAbsolute(specifiedFile)) {
return specifiedFile;
}
return path.join(process.cwd(), specifiedFile);
}
// This is not being called with an arg. Use the package.json `main`
return require(path.join(process.cwd(), 'package.json')).main;
}
function _getConfigs(configFile, files) {
const cliEngine = eslint.ESLint
? new eslint.ESLint({
// Ignore any config applicable depending on the location on the filesystem
useEslintrc: false,
// Point to the particular config
overrideConfigFile: configFile
})
: new eslint.CLIEngine({
// Ignore any config applicable depending on the location on the filesystem
useEslintrc: false,
// Point to the particular config
configFile
});
return new Set(files
.map(filePath => cliEngine.isPathIgnored(filePath) ? false : cliEngine.getConfigForFile(filePath))
.filter(Boolean));
}
function _getConfig(configFile, files) {
return Array.from(_getConfigs(configFile, files)).reduce((prev, item) => {
return Object.assign(prev, item, {rules: Object.assign({}, prev.rules, item.rules)});
}, {});
}
function _getCurrentNamesRules(config) {
return config.rules ? Object.keys(config.rules) : [];
}
function _isDeprecated(rule) {
return rule && rule.meta && rule.meta.deprecated;
}
function _notDeprecated(rule) {
return !_isDeprecated(rule);
}
function _getPluginRules(config) {
const pluginRules = new Map();
const plugins = config.plugins;
/* istanbul ignore else */
if (plugins) {
plugins.forEach(plugin => {
const normalized = normalizePluginName(plugin);
const pluginConfig = require(normalized.module);
const rules = pluginConfig.rules === undefined ? {} : pluginConfig.rules;
Object.keys(rules).forEach(ruleName =>
pluginRules.set(`${normalized.prefix}/${ruleName}`, rules[ruleName])
);
});
}
return pluginRules;
}
function _getCoreRules() {
return (eslint.Linter ? new eslint.Linter() : eslint.linter).getRules();
}
function _filterRuleNames(ruleNames, rules, predicate) {
return ruleNames.filter(ruleName => predicate(rules.get(ruleName)));
}
function _isNotCore(rule) {
return rule.indexOf('/') !== '-1';
}
function _escapeRegExp(str) {
return str.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&');
}
function _createExtensionRegExp(extensions) {
const normalizedExts = extensions.map(ext => _escapeRegExp(
ext.startsWith('.') ? ext.slice(1) : ext
));
return new RegExp(`.\\.(?:${normalizedExts.join("|")})$`);
}
function RuleFinder(specifiedFile, {omitCore, includeDeprecated, ext = ['.js']}) {
const configFile = _getConfigFile(specifiedFile);
const extensionRegExp = _createExtensionRegExp(ext);
const files = glob.sync(`**/*`, {dot: true, matchBase: true})
.filter(file => extensionRegExp.test(file));
const config = _getConfig(configFile, files);
let currentRuleNames = _getCurrentNamesRules(config);
if (omitCore) {
currentRuleNames = currentRuleNames.filter(_isNotCore);
}
const pluginRules = _getPluginRules(config); // eslint-disable-line vars-on-top
const coreRules = _getCoreRules();
const allRules = omitCore ? pluginRules : new Map([...coreRules, ...pluginRules]);
let allRuleNames = [...allRules.keys()];
let pluginRuleNames = [...pluginRules.keys()];
if (!includeDeprecated) {
allRuleNames = _filterRuleNames(allRuleNames, allRules, _notDeprecated);
pluginRuleNames = _filterRuleNames(pluginRuleNames, pluginRules, _notDeprecated);
}
const deprecatedRuleNames = _filterRuleNames(currentRuleNames, allRules, _isDeprecated);
const dedupedRuleNames = [...new Set(allRuleNames)];
const unusedRuleNames = difference(dedupedRuleNames, currentRuleNames);
// Get all the current rules instead of referring the extended files or documentation
this.getCurrentRules = () => getSortedRules(currentRuleNames);
// Get all the current rules' particular configuration
this.getCurrentRulesDetailed = () => config.rules;
// Get all the plugin rules instead of referring the extended files or documentation
this.getPluginRules = () => getSortedRules(pluginRuleNames);
// Get all the available rules instead of referring eslint and plugin packages or documentation
this.getAllAvailableRules = () => getSortedRules(dedupedRuleNames);
this.getUnusedRules = () => getSortedRules(unusedRuleNames);
// Get all the current rules that are deprecated
this.getDeprecatedRules = () => getSortedRules(deprecatedRuleNames);
}
module.exports = function (specifiedFile, options = {}) {
return new RuleFinder(specifiedFile, options);
};