isml-linter 5.39.3 → 5.40.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1184 -1159
- package/LICENSE +21 -21
- package/README.md +245 -245
- package/bin/isml-linter.js +32 -32
- package/ismllinter.config.js +33 -33
- package/package.json +53 -53
- package/scaffold_files/ismllinter.config.js +47 -47
- package/src/Builder.js +15 -15
- package/src/Constants.js +139 -139
- package/src/IsmlLinter.js +255 -255
- package/src/enums/ParseStatus.js +5 -5
- package/src/enums/SfccTagContainer.js +287 -287
- package/src/isml_tree/ContainerNode.js +38 -38
- package/src/isml_tree/IsmlNode.js +692 -684
- package/src/isml_tree/MaskUtils.js +421 -421
- package/src/isml_tree/ParseUtils.js +532 -506
- package/src/isml_tree/TreeBuilder.js +273 -273
- package/src/publicApi.js +24 -24
- package/src/rules/line_by_line/enforce-isprint.js +53 -53
- package/src/rules/line_by_line/enforce-require.js +35 -35
- package/src/rules/line_by_line/lowercase-filename.js +29 -29
- package/src/rules/line_by_line/max-lines.js +37 -37
- package/src/rules/line_by_line/no-br.js +36 -36
- package/src/rules/line_by_line/no-git-conflict.js +43 -43
- package/src/rules/line_by_line/no-import-package.js +34 -34
- package/src/rules/line_by_line/no-inline-style.js +34 -34
- package/src/rules/line_by_line/no-isscript.js +34 -34
- package/src/rules/line_by_line/no-space-only-lines.js +47 -47
- package/src/rules/line_by_line/no-tabs.js +38 -38
- package/src/rules/line_by_line/no-trailing-spaces.js +52 -52
- package/src/rules/prototypes/RulePrototype.js +79 -79
- package/src/rules/prototypes/SingleLineRulePrototype.js +47 -47
- package/src/rules/prototypes/TreeRulePrototype.js +84 -84
- package/src/rules/tree/align-isset.js +87 -87
- package/src/rules/tree/contextual-attrs.js +105 -105
- package/src/rules/tree/custom-tags.js +54 -54
- package/src/rules/tree/disallow-tags.js +39 -39
- package/src/rules/tree/empty-eof.js +66 -66
- package/src/rules/tree/enforce-security.js +85 -85
- package/src/rules/tree/eslint-to-isscript.js +179 -179
- package/src/rules/tree/indent.js +856 -853
- package/src/rules/tree/leading-iscache.js +39 -39
- package/src/rules/tree/leading-iscontent.js +35 -35
- package/src/rules/tree/max-depth.js +54 -54
- package/src/rules/tree/no-deprecated-attrs.js +67 -67
- package/src/rules/tree/no-embedded-isml.js +17 -17
- package/src/rules/tree/no-hardcode.js +51 -51
- package/src/rules/tree/no-iselse-slash.js +35 -35
- package/src/rules/tree/no-redundant-context.js +134 -134
- package/src/rules/tree/no-require-in-loop.js +63 -63
- package/src/rules/tree/one-element-per-line.js +82 -76
- package/src/util/CommandLineUtils.js +19 -19
- package/src/util/ConfigUtils.js +219 -219
- package/src/util/ConsoleUtils.js +327 -327
- package/src/util/CustomTagContainer.js +45 -45
- package/src/util/ExceptionUtils.js +173 -149
- package/src/util/FileUtils.js +79 -79
- package/src/util/GeneralUtils.js +60 -60
- package/src/util/NativeExtensionUtils.js +6 -6
- package/src/util/RuleUtils.js +295 -295
- package/src/util/TempRuleUtils.js +232 -232
package/src/util/RuleUtils.js
CHANGED
|
@@ -1,295 +1,295 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const Constants = require('../Constants');
|
|
4
|
-
const TreeBuilder = require('../isml_tree/TreeBuilder');
|
|
5
|
-
const ConfigUtils = require('./ConfigUtils');
|
|
6
|
-
const lowercaseFilenameRule = require('../rules/line_by_line/lowercase-filename');
|
|
7
|
-
const CustomTagContainer = require('./CustomTagContainer');
|
|
8
|
-
const CustomModulesRule = require('../rules/tree/custom-tags');
|
|
9
|
-
const GeneralUtils = require('./GeneralUtils');
|
|
10
|
-
const ConsoleUtils = require('./ConsoleUtils');
|
|
11
|
-
const ExceptionUtils = require('./ExceptionUtils');
|
|
12
|
-
|
|
13
|
-
const lineByLineRules = [];
|
|
14
|
-
const treeRules = [];
|
|
15
|
-
|
|
16
|
-
(() => {
|
|
17
|
-
const lineRuleFileArray = fs.readdirSync(Constants.lineByLineRulesDir);
|
|
18
|
-
const treeRuleFileArray = fs.readdirSync(Constants.treeRulesDir);
|
|
19
|
-
|
|
20
|
-
for (let i = 0; i < lineRuleFileArray.length; i++) {
|
|
21
|
-
const file = lineRuleFileArray[i];
|
|
22
|
-
|
|
23
|
-
if (file.endsWith('.js')) {
|
|
24
|
-
const rulePath = path.join(__dirname, '..', 'rules', 'line_by_line', file);
|
|
25
|
-
lineByLineRules.push(require(rulePath));
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
for (let i = 0; i < treeRuleFileArray.length; i++) {
|
|
30
|
-
const file = treeRuleFileArray[i];
|
|
31
|
-
|
|
32
|
-
if (file.endsWith('.js')) {
|
|
33
|
-
const rulePath = path.join(__dirname, '..', 'rules', 'tree', file);
|
|
34
|
-
treeRules.push(require(rulePath));
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
})();
|
|
38
|
-
|
|
39
|
-
const getLevelGroup = level => {
|
|
40
|
-
return level === 'errors' ? 'errors' :
|
|
41
|
-
level === 'warning' ? 'warnings' :
|
|
42
|
-
'info';
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const checkCustomTag = tag => {
|
|
46
|
-
if (Object.prototype.hasOwnProperty.call(CustomTagContainer, tag)) {
|
|
47
|
-
const attrList = CustomTagContainer[tag].attrList;
|
|
48
|
-
|
|
49
|
-
for (let i = 0; i < attrList.length; i++) {
|
|
50
|
-
const attr = attrList[i];
|
|
51
|
-
if (attr !== attr.toLowerCase()) {
|
|
52
|
-
return {
|
|
53
|
-
line : '',
|
|
54
|
-
globalPos : 0,
|
|
55
|
-
length : 10,
|
|
56
|
-
lineNumber : 1,
|
|
57
|
-
columnNumber : 1,
|
|
58
|
-
level : CustomModulesRule.level,
|
|
59
|
-
rule : CustomModulesRule.id,
|
|
60
|
-
message : `Module properties need to be lower case: "${tag}" module has the invalid "${attr}" attribute`
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
const applyRuleResult = (config, ruleResult, templatePath, templateResults, rule) => {
|
|
68
|
-
if (config.autoFix && ruleResult.fixedContent) {
|
|
69
|
-
fs.writeFileSync(templatePath, ruleResult.fixedContent);
|
|
70
|
-
templateResults.fixed = true;
|
|
71
|
-
}
|
|
72
|
-
else if (ruleResult.occurrenceList && ruleResult.occurrenceList.length) {
|
|
73
|
-
const occurrenceObj = getOccurrenceObj(rule, ruleResult.occurrenceList);
|
|
74
|
-
|
|
75
|
-
templateResults.errors = Object.assign(templateResults.errors, occurrenceObj.errors);
|
|
76
|
-
templateResults.warnings = Object.assign(templateResults.warnings, occurrenceObj.warnings);
|
|
77
|
-
templateResults.info = Object.assign(templateResults.info, occurrenceObj.info);
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
const applyRuleOnTemplate = (ruleArray, templatePath, root, config, data) => {
|
|
82
|
-
const templateResults = {
|
|
83
|
-
fixed : false,
|
|
84
|
-
errors : {},
|
|
85
|
-
warnings : {},
|
|
86
|
-
info : {},
|
|
87
|
-
data
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
for (let i = 0; i < ruleArray.length; i++) {
|
|
91
|
-
const rule = ruleArray[i];
|
|
92
|
-
if (!rule.shouldIgnore(templatePath)) {
|
|
93
|
-
try {
|
|
94
|
-
ConsoleUtils.displayVerboseMessage(`Applying "${rule.id}" rule`, 1);
|
|
95
|
-
const ruleResults = rule.check(root, templateResults.data);
|
|
96
|
-
applyRuleResult(config, ruleResults, templatePath, templateResults, rule);
|
|
97
|
-
|
|
98
|
-
} catch (error) {
|
|
99
|
-
throw ExceptionUtils.ruleApplianceError(rule, error, templatePath);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return templateResults;
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
const findNodeOfType = (node, type) => {
|
|
108
|
-
let result = null;
|
|
109
|
-
|
|
110
|
-
node.children.some( child => {
|
|
111
|
-
if (child.isOfType(type)) {
|
|
112
|
-
result = child;
|
|
113
|
-
return true;
|
|
114
|
-
} else {
|
|
115
|
-
result = findNodeOfType(child, type) || result;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return false;
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
return result;
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
const isTypeAmongTheFirstElements = (rootNode, type) => {
|
|
125
|
-
let result = false;
|
|
126
|
-
|
|
127
|
-
for (let i = 0; i < Constants.leadingElementsChecking; i++) {
|
|
128
|
-
result = result ||
|
|
129
|
-
rootNode.children[i] &&
|
|
130
|
-
rootNode.children[i].isOfType(type);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return result;
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
const getOccurrenceObj = (rule, occurrenceArray) => {
|
|
137
|
-
const occurrenceGroup = getLevelGroup(rule.level);
|
|
138
|
-
|
|
139
|
-
const occurrenceObj = {};
|
|
140
|
-
occurrenceObj[occurrenceGroup] = {};
|
|
141
|
-
occurrenceObj[occurrenceGroup][rule.id] = [];
|
|
142
|
-
|
|
143
|
-
for (let i = 0; i < occurrenceArray.length; i++) {
|
|
144
|
-
const occurrence = occurrenceArray[i];
|
|
145
|
-
occurrenceObj[occurrenceGroup][rule.id].push(occurrence);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return occurrenceObj;
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
const checkFileName = (filename, templateContent) => {
|
|
152
|
-
const occurrenceGroup = getLevelGroup(lowercaseFilenameRule.level);
|
|
153
|
-
const templateResults = {
|
|
154
|
-
fixed : false,
|
|
155
|
-
errors : {},
|
|
156
|
-
warnings : {},
|
|
157
|
-
info : {}
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
if (lowercaseFilenameRule.isEnabled()) {
|
|
161
|
-
const ruleResult = lowercaseFilenameRule.check(filename, templateContent);
|
|
162
|
-
|
|
163
|
-
if (ruleResult.occurrenceList.length > 0) {
|
|
164
|
-
const occurrenceObj = getOccurrenceObj(lowercaseFilenameRule, ruleResult.occurrenceList);
|
|
165
|
-
templateResults[occurrenceGroup] = Object.assign(templateResults[occurrenceGroup], occurrenceObj[occurrenceGroup]);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
return templateResults;
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
const checkTreeRules = (templatePath, templateContent, config, data) => {
|
|
173
|
-
if (!config.disableTreeParse) {
|
|
174
|
-
ConsoleUtils.displayVerboseMessage(`Building tree for "${templatePath}"`, 1);
|
|
175
|
-
const tree = TreeBuilder.build(templatePath, templateContent);
|
|
176
|
-
|
|
177
|
-
if (!tree.rootNode) {
|
|
178
|
-
throw tree.exception;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
const ruleArray = getEnabledTreeRules();
|
|
182
|
-
|
|
183
|
-
return applyRuleOnTemplate(
|
|
184
|
-
ruleArray,
|
|
185
|
-
templatePath,
|
|
186
|
-
tree.rootNode,
|
|
187
|
-
config,
|
|
188
|
-
data);
|
|
189
|
-
}
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
const checkLineByLineRules = (templatePath, templateContent, config, data) => {
|
|
193
|
-
const ruleArray = getEnabledLineRules();
|
|
194
|
-
|
|
195
|
-
return applyRuleOnTemplate(
|
|
196
|
-
ruleArray,
|
|
197
|
-
templatePath,
|
|
198
|
-
templateContent,
|
|
199
|
-
config,
|
|
200
|
-
data);
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
const checkCustomModules = () => {
|
|
204
|
-
const occurrenceGroup = getLevelGroup(CustomModulesRule.level);
|
|
205
|
-
const moduleResults = {
|
|
206
|
-
errors : [],
|
|
207
|
-
warnings : [],
|
|
208
|
-
info : []
|
|
209
|
-
};
|
|
210
|
-
|
|
211
|
-
if (CustomModulesRule.isEnabled()) {
|
|
212
|
-
for (const tag in CustomTagContainer) {
|
|
213
|
-
const occurrenceObj = checkCustomTag(tag);
|
|
214
|
-
|
|
215
|
-
if (occurrenceObj) {
|
|
216
|
-
moduleResults[occurrenceGroup].push(occurrenceObj);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
return moduleResults;
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
const checkTemplate = (templatePath, data, content = '', templateName = '') => {
|
|
225
|
-
ConsoleUtils.displayVerboseMessage(`\nChecking "${templatePath}" template`);
|
|
226
|
-
const config = ConfigUtils.load();
|
|
227
|
-
const templateContent = GeneralUtils.toLF(content || fs.readFileSync(templatePath, 'utf-8'));
|
|
228
|
-
const lineResults = checkLineByLineRules(templatePath, templateContent, config, data);
|
|
229
|
-
const treeResults = checkTreeRules(templatePath, templateContent, config, data) || { errors : [] };
|
|
230
|
-
const filenameResults = checkFileName(templateName, templateContent);
|
|
231
|
-
|
|
232
|
-
return {
|
|
233
|
-
fixed : lineResults.fixed || treeResults.fixed,
|
|
234
|
-
treeData : treeResults.data,
|
|
235
|
-
errors : {
|
|
236
|
-
...lineResults.errors,
|
|
237
|
-
...treeResults.errors,
|
|
238
|
-
...filenameResults.errors
|
|
239
|
-
},
|
|
240
|
-
warnings : {
|
|
241
|
-
...lineResults.warnings,
|
|
242
|
-
...treeResults.warnings,
|
|
243
|
-
...filenameResults.warnings
|
|
244
|
-
},
|
|
245
|
-
info : {
|
|
246
|
-
...lineResults.info,
|
|
247
|
-
...treeResults.info,
|
|
248
|
-
...filenameResults.info
|
|
249
|
-
}
|
|
250
|
-
};
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
const getAvailableRulesQty = () => treeRules.length + lineByLineRules.length;
|
|
254
|
-
|
|
255
|
-
const getEnabledLineRules = () => {
|
|
256
|
-
const result = [];
|
|
257
|
-
|
|
258
|
-
for (let i = 0; i < lineByLineRules.length; i++) {
|
|
259
|
-
const rule = lineByLineRules[i];
|
|
260
|
-
|
|
261
|
-
// TODO Do this in a better way;
|
|
262
|
-
rule.level = rule.getConfigs().level || 'errors';
|
|
263
|
-
|
|
264
|
-
if (rule.isEnabled() && rule.id !== 'lowercase-filename') {
|
|
265
|
-
result.push(rule);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
return result;
|
|
270
|
-
};
|
|
271
|
-
|
|
272
|
-
const getEnabledTreeRules = () => {
|
|
273
|
-
const result = [];
|
|
274
|
-
|
|
275
|
-
for (let i = 0; i < treeRules.length; i++) {
|
|
276
|
-
const rule = treeRules[i];
|
|
277
|
-
|
|
278
|
-
// TODO Do this in a better way;
|
|
279
|
-
rule.level = rule.getConfigs().level || 'errors';
|
|
280
|
-
|
|
281
|
-
if (rule.isEnabled()) {
|
|
282
|
-
result.push(rule);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
return result;
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
module.exports.getAllLineRules = () => lineByLineRules;
|
|
290
|
-
module.exports.findNodeOfType = findNodeOfType;
|
|
291
|
-
module.exports.isTypeAmongTheFirstElements = isTypeAmongTheFirstElements;
|
|
292
|
-
module.exports.checkTemplate = checkTemplate;
|
|
293
|
-
module.exports.checkCustomModules = checkCustomModules;
|
|
294
|
-
module.exports.getAvailableRulesQty = getAvailableRulesQty;
|
|
295
|
-
module.exports.getLevelGroup = getLevelGroup;
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const Constants = require('../Constants');
|
|
4
|
+
const TreeBuilder = require('../isml_tree/TreeBuilder');
|
|
5
|
+
const ConfigUtils = require('./ConfigUtils');
|
|
6
|
+
const lowercaseFilenameRule = require('../rules/line_by_line/lowercase-filename');
|
|
7
|
+
const CustomTagContainer = require('./CustomTagContainer');
|
|
8
|
+
const CustomModulesRule = require('../rules/tree/custom-tags');
|
|
9
|
+
const GeneralUtils = require('./GeneralUtils');
|
|
10
|
+
const ConsoleUtils = require('./ConsoleUtils');
|
|
11
|
+
const ExceptionUtils = require('./ExceptionUtils');
|
|
12
|
+
|
|
13
|
+
const lineByLineRules = [];
|
|
14
|
+
const treeRules = [];
|
|
15
|
+
|
|
16
|
+
(() => {
|
|
17
|
+
const lineRuleFileArray = fs.readdirSync(Constants.lineByLineRulesDir);
|
|
18
|
+
const treeRuleFileArray = fs.readdirSync(Constants.treeRulesDir);
|
|
19
|
+
|
|
20
|
+
for (let i = 0; i < lineRuleFileArray.length; i++) {
|
|
21
|
+
const file = lineRuleFileArray[i];
|
|
22
|
+
|
|
23
|
+
if (file.endsWith('.js')) {
|
|
24
|
+
const rulePath = path.join(__dirname, '..', 'rules', 'line_by_line', file);
|
|
25
|
+
lineByLineRules.push(require(rulePath));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
for (let i = 0; i < treeRuleFileArray.length; i++) {
|
|
30
|
+
const file = treeRuleFileArray[i];
|
|
31
|
+
|
|
32
|
+
if (file.endsWith('.js')) {
|
|
33
|
+
const rulePath = path.join(__dirname, '..', 'rules', 'tree', file);
|
|
34
|
+
treeRules.push(require(rulePath));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
})();
|
|
38
|
+
|
|
39
|
+
const getLevelGroup = level => {
|
|
40
|
+
return level === 'errors' ? 'errors' :
|
|
41
|
+
level === 'warning' ? 'warnings' :
|
|
42
|
+
'info';
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const checkCustomTag = tag => {
|
|
46
|
+
if (Object.prototype.hasOwnProperty.call(CustomTagContainer, tag)) {
|
|
47
|
+
const attrList = CustomTagContainer[tag].attrList;
|
|
48
|
+
|
|
49
|
+
for (let i = 0; i < attrList.length; i++) {
|
|
50
|
+
const attr = attrList[i];
|
|
51
|
+
if (attr !== attr.toLowerCase()) {
|
|
52
|
+
return {
|
|
53
|
+
line : '',
|
|
54
|
+
globalPos : 0,
|
|
55
|
+
length : 10,
|
|
56
|
+
lineNumber : 1,
|
|
57
|
+
columnNumber : 1,
|
|
58
|
+
level : CustomModulesRule.level,
|
|
59
|
+
rule : CustomModulesRule.id,
|
|
60
|
+
message : `Module properties need to be lower case: "${tag}" module has the invalid "${attr}" attribute`
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const applyRuleResult = (config, ruleResult, templatePath, templateResults, rule) => {
|
|
68
|
+
if (config.autoFix && ruleResult.fixedContent) {
|
|
69
|
+
fs.writeFileSync(templatePath, ruleResult.fixedContent);
|
|
70
|
+
templateResults.fixed = true;
|
|
71
|
+
}
|
|
72
|
+
else if (ruleResult.occurrenceList && ruleResult.occurrenceList.length) {
|
|
73
|
+
const occurrenceObj = getOccurrenceObj(rule, ruleResult.occurrenceList);
|
|
74
|
+
|
|
75
|
+
templateResults.errors = Object.assign(templateResults.errors, occurrenceObj.errors);
|
|
76
|
+
templateResults.warnings = Object.assign(templateResults.warnings, occurrenceObj.warnings);
|
|
77
|
+
templateResults.info = Object.assign(templateResults.info, occurrenceObj.info);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const applyRuleOnTemplate = (ruleArray, templatePath, root, config, data) => {
|
|
82
|
+
const templateResults = {
|
|
83
|
+
fixed : false,
|
|
84
|
+
errors : {},
|
|
85
|
+
warnings : {},
|
|
86
|
+
info : {},
|
|
87
|
+
data
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
for (let i = 0; i < ruleArray.length; i++) {
|
|
91
|
+
const rule = ruleArray[i];
|
|
92
|
+
if (!rule.shouldIgnore(templatePath)) {
|
|
93
|
+
try {
|
|
94
|
+
ConsoleUtils.displayVerboseMessage(`Applying "${rule.id}" rule`, 1);
|
|
95
|
+
const ruleResults = rule.check(root, templateResults.data);
|
|
96
|
+
applyRuleResult(config, ruleResults, templatePath, templateResults, rule);
|
|
97
|
+
|
|
98
|
+
} catch (error) {
|
|
99
|
+
throw ExceptionUtils.ruleApplianceError(rule, error, templatePath);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return templateResults;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const findNodeOfType = (node, type) => {
|
|
108
|
+
let result = null;
|
|
109
|
+
|
|
110
|
+
node.children.some( child => {
|
|
111
|
+
if (child.isOfType(type)) {
|
|
112
|
+
result = child;
|
|
113
|
+
return true;
|
|
114
|
+
} else {
|
|
115
|
+
result = findNodeOfType(child, type) || result;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return false;
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
return result;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const isTypeAmongTheFirstElements = (rootNode, type) => {
|
|
125
|
+
let result = false;
|
|
126
|
+
|
|
127
|
+
for (let i = 0; i < Constants.leadingElementsChecking; i++) {
|
|
128
|
+
result = result ||
|
|
129
|
+
rootNode.children[i] &&
|
|
130
|
+
rootNode.children[i].isOfType(type);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return result;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const getOccurrenceObj = (rule, occurrenceArray) => {
|
|
137
|
+
const occurrenceGroup = getLevelGroup(rule.level);
|
|
138
|
+
|
|
139
|
+
const occurrenceObj = {};
|
|
140
|
+
occurrenceObj[occurrenceGroup] = {};
|
|
141
|
+
occurrenceObj[occurrenceGroup][rule.id] = [];
|
|
142
|
+
|
|
143
|
+
for (let i = 0; i < occurrenceArray.length; i++) {
|
|
144
|
+
const occurrence = occurrenceArray[i];
|
|
145
|
+
occurrenceObj[occurrenceGroup][rule.id].push(occurrence);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return occurrenceObj;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
const checkFileName = (filename, templateContent) => {
|
|
152
|
+
const occurrenceGroup = getLevelGroup(lowercaseFilenameRule.level);
|
|
153
|
+
const templateResults = {
|
|
154
|
+
fixed : false,
|
|
155
|
+
errors : {},
|
|
156
|
+
warnings : {},
|
|
157
|
+
info : {}
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
if (lowercaseFilenameRule.isEnabled()) {
|
|
161
|
+
const ruleResult = lowercaseFilenameRule.check(filename, templateContent);
|
|
162
|
+
|
|
163
|
+
if (ruleResult.occurrenceList.length > 0) {
|
|
164
|
+
const occurrenceObj = getOccurrenceObj(lowercaseFilenameRule, ruleResult.occurrenceList);
|
|
165
|
+
templateResults[occurrenceGroup] = Object.assign(templateResults[occurrenceGroup], occurrenceObj[occurrenceGroup]);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return templateResults;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
const checkTreeRules = (templatePath, templateContent, config, data) => {
|
|
173
|
+
if (!config.disableTreeParse) {
|
|
174
|
+
ConsoleUtils.displayVerboseMessage(`Building tree for "${templatePath}"`, 1);
|
|
175
|
+
const tree = TreeBuilder.build(templatePath, templateContent);
|
|
176
|
+
|
|
177
|
+
if (!tree.rootNode) {
|
|
178
|
+
throw tree.exception;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const ruleArray = getEnabledTreeRules();
|
|
182
|
+
|
|
183
|
+
return applyRuleOnTemplate(
|
|
184
|
+
ruleArray,
|
|
185
|
+
templatePath,
|
|
186
|
+
tree.rootNode,
|
|
187
|
+
config,
|
|
188
|
+
data);
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const checkLineByLineRules = (templatePath, templateContent, config, data) => {
|
|
193
|
+
const ruleArray = getEnabledLineRules();
|
|
194
|
+
|
|
195
|
+
return applyRuleOnTemplate(
|
|
196
|
+
ruleArray,
|
|
197
|
+
templatePath,
|
|
198
|
+
templateContent,
|
|
199
|
+
config,
|
|
200
|
+
data);
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
const checkCustomModules = () => {
|
|
204
|
+
const occurrenceGroup = getLevelGroup(CustomModulesRule.level);
|
|
205
|
+
const moduleResults = {
|
|
206
|
+
errors : [],
|
|
207
|
+
warnings : [],
|
|
208
|
+
info : []
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
if (CustomModulesRule.isEnabled()) {
|
|
212
|
+
for (const tag in CustomTagContainer) {
|
|
213
|
+
const occurrenceObj = checkCustomTag(tag);
|
|
214
|
+
|
|
215
|
+
if (occurrenceObj) {
|
|
216
|
+
moduleResults[occurrenceGroup].push(occurrenceObj);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return moduleResults;
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
const checkTemplate = (templatePath, data, content = '', templateName = '') => {
|
|
225
|
+
ConsoleUtils.displayVerboseMessage(`\nChecking "${templatePath}" template`);
|
|
226
|
+
const config = ConfigUtils.load();
|
|
227
|
+
const templateContent = GeneralUtils.toLF(content || fs.readFileSync(templatePath, 'utf-8'));
|
|
228
|
+
const lineResults = checkLineByLineRules(templatePath, templateContent, config, data);
|
|
229
|
+
const treeResults = checkTreeRules(templatePath, templateContent, config, data) || { errors : [] };
|
|
230
|
+
const filenameResults = checkFileName(templateName, templateContent);
|
|
231
|
+
|
|
232
|
+
return {
|
|
233
|
+
fixed : lineResults.fixed || treeResults.fixed,
|
|
234
|
+
treeData : treeResults.data,
|
|
235
|
+
errors : {
|
|
236
|
+
...lineResults.errors,
|
|
237
|
+
...treeResults.errors,
|
|
238
|
+
...filenameResults.errors
|
|
239
|
+
},
|
|
240
|
+
warnings : {
|
|
241
|
+
...lineResults.warnings,
|
|
242
|
+
...treeResults.warnings,
|
|
243
|
+
...filenameResults.warnings
|
|
244
|
+
},
|
|
245
|
+
info : {
|
|
246
|
+
...lineResults.info,
|
|
247
|
+
...treeResults.info,
|
|
248
|
+
...filenameResults.info
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
const getAvailableRulesQty = () => treeRules.length + lineByLineRules.length;
|
|
254
|
+
|
|
255
|
+
const getEnabledLineRules = () => {
|
|
256
|
+
const result = [];
|
|
257
|
+
|
|
258
|
+
for (let i = 0; i < lineByLineRules.length; i++) {
|
|
259
|
+
const rule = lineByLineRules[i];
|
|
260
|
+
|
|
261
|
+
// TODO Do this in a better way;
|
|
262
|
+
rule.level = rule.getConfigs().level || 'errors';
|
|
263
|
+
|
|
264
|
+
if (rule.isEnabled() && rule.id !== 'lowercase-filename') {
|
|
265
|
+
result.push(rule);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return result;
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
const getEnabledTreeRules = () => {
|
|
273
|
+
const result = [];
|
|
274
|
+
|
|
275
|
+
for (let i = 0; i < treeRules.length; i++) {
|
|
276
|
+
const rule = treeRules[i];
|
|
277
|
+
|
|
278
|
+
// TODO Do this in a better way;
|
|
279
|
+
rule.level = rule.getConfigs().level || 'errors';
|
|
280
|
+
|
|
281
|
+
if (rule.isEnabled()) {
|
|
282
|
+
result.push(rule);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return result;
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
module.exports.getAllLineRules = () => lineByLineRules;
|
|
290
|
+
module.exports.findNodeOfType = findNodeOfType;
|
|
291
|
+
module.exports.isTypeAmongTheFirstElements = isTypeAmongTheFirstElements;
|
|
292
|
+
module.exports.checkTemplate = checkTemplate;
|
|
293
|
+
module.exports.checkCustomModules = checkCustomModules;
|
|
294
|
+
module.exports.getAvailableRulesQty = getAvailableRulesQty;
|
|
295
|
+
module.exports.getLevelGroup = getLevelGroup;
|