isml-linter 5.40.5 → 5.42.0
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 +30 -8
- package/README.md +4 -2
- package/package.json +1 -1
- package/scaffold_files/ismllinter.config.js +1 -0
- package/src/IsmlLinter.js +3 -3
- package/src/isml_tree/IsmlNode.js +1 -0
- package/src/isml_tree/ParseUtils.js +1 -1
- package/src/isml_tree/TreeBuilder.js +2 -8
- package/src/publicApi.js +15 -0
- package/src/rules/prototypes/SingleLineRulePrototype.js +4 -1
- package/src/rules/tree/indent.js +6 -0
- package/src/rules/tree/strict-void-elements.js +46 -0
- package/src/util/ConfigUtils.js +1 -1
- package/src/util/RuleUtils.js +15 -14
- package/src/util/TempRuleUtils.js +11 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [5.42.0] - 2023-01-25
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- Introducing ["strict-void-elements" rule][strict-void-elements-readme];
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
- Allow Closing Tags for Void Elements in AST. "strict-void-elements" rule will optionally handle that invalid scenario;
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
- "indent" Rule - Add "line" Attribute to Quote Issue Report;
|
|
13
|
+
|
|
14
|
+
## [5.41.0] - 2023-01-21
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- Exposed "fix" method in [ISML Linter API][api-docs];
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
- Line-by-line and tree rules issues now are fixed in a single ISML Linter execution, not in two steps anymore;
|
|
21
|
+
|
|
3
22
|
## [5.40.5] - 2023-01-15
|
|
4
23
|
|
|
5
24
|
### Fixed
|
|
@@ -1040,6 +1059,8 @@
|
|
|
1040
1059
|
### Added
|
|
1041
1060
|
- Linter is published;
|
|
1042
1061
|
|
|
1062
|
+
[5.42.0]: https://github.com/FabiowQuixada/isml-linter/compare/v5.41.0...v5.42.0
|
|
1063
|
+
[5.41.0]: https://github.com/FabiowQuixada/isml-linter/compare/v5.40.5...v5.41.0
|
|
1043
1064
|
[5.40.5]: https://github.com/FabiowQuixada/isml-linter/compare/v5.40.4...v5.40.5
|
|
1044
1065
|
[5.40.4]: https://github.com/FabiowQuixada/isml-linter/compare/v5.40.3...v5.40.4
|
|
1045
1066
|
[5.40.3]: https://github.com/FabiowQuixada/isml-linter/compare/v5.40.2...v5.40.3
|
|
@@ -1202,11 +1223,12 @@
|
|
|
1202
1223
|
[api-docs]: <docs/api.md>
|
|
1203
1224
|
[license]: <LICENSE>
|
|
1204
1225
|
|
|
1205
|
-
[
|
|
1206
|
-
[
|
|
1207
|
-
[no-
|
|
1208
|
-
[no-
|
|
1209
|
-
[
|
|
1210
|
-
[
|
|
1211
|
-
[
|
|
1212
|
-
[
|
|
1226
|
+
[strict-void-elements-readme]: <docs/rules/strict-void-elements.md>
|
|
1227
|
+
[disallow-tags-readme]: <docs/rules/disallow-tags.md>
|
|
1228
|
+
[no-br-readme]: <docs/rules/no-br.md>
|
|
1229
|
+
[no-inline-style-readme]: <docs/rules/no-br.md>
|
|
1230
|
+
[no-isscript-readme]: <docs/rules/no-isscript.md>
|
|
1231
|
+
[enforce-security-readme]: <docs/rules/enforce-security.md>
|
|
1232
|
+
[no-hardcode-readme]: <docs/rules/no-hardcode.md>
|
|
1233
|
+
[indent-readme]: <docs/rules/indent.md>
|
|
1234
|
+
[eslint-to-isscript-readme]: <docs/rules/eslint-to-isscript.md>
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@ ISML Linter is a tool for examining if your project's templates follow a specifi
|
|
|
3
3
|
|
|
4
4
|
- Styles that are defined by your team;
|
|
5
5
|
- Syntactic errors related to `<is* >` tags;
|
|
6
|
-
- Coding conventions recommended by
|
|
6
|
+
- Coding conventions recommended by Salesforce;
|
|
7
7
|
- Git conflicts that may accidentally be left unresolved;
|
|
8
8
|
|
|
9
9
|
Please feel free to make suggestions and help make this linter better. :) The set of currently available rules can be found below.
|
|
@@ -161,7 +161,7 @@ Please check the [Generic Configurations for Rules][generic-rule-config] page.
|
|
|
161
161
|
| ------------------------------------------------------------------------------------ |:-----------------------------------------|
|
|
162
162
|
| :exclamation: [no-br][no-br-readme] | <span style="color:orange">[Deprecated]</span> Disallows `<br/>` tags. Enable this rule if you prefer to use CSS to handle vertical spacing |
|
|
163
163
|
| [no-git-conflict][no-git-conflict-readme] | Disallows unresolved Git conflicts |
|
|
164
|
-
| [no-import-package][no-import-package-readme] | Disallows `importPackage()` function. It is recommended by
|
|
164
|
+
| [no-import-package][no-import-package-readme] | Disallows `importPackage()` function. It is recommended by Salesforce to use `require()` instead |
|
|
165
165
|
| :exclamation: [no-isscript][no-isscript-readme] | <span style="color:orange">[Deprecated]</span> Disallows `<isscript/>` tag in template. Enable this rule if you prefer logic to be kept in a separate .ds/.js file |
|
|
166
166
|
| :wrench: [no-trailing-spaces][no-trailing-spaces-readme] | Disallows trailing blank spaces |
|
|
167
167
|
| :wrench: [no-space-only-lines][no-space-only-lines-readme] | Disallows lines that contain only blank spaces, i.e., unnecessarily indented |
|
|
@@ -189,6 +189,7 @@ Please check the [Generic Configurations for Rules][generic-rule-config] page.
|
|
|
189
189
|
| :small_orange_diamond: [align-isset][align-isset-readme] | Aligns contiguous `<isset>` tags attributes' columns |
|
|
190
190
|
| :small_orange_diamond: [enforce-security][enforce-security-readme] | Enforces security measures |
|
|
191
191
|
| :wrench: :small_orange_diamond: [no-redundant-context][no-redundant-context-readme] | Prevents use of unnecessary contexts, such as `dw.web.Resource` |
|
|
192
|
+
| :small_orange_diamond: [strict-void-elements][strict-void-elements-readme] | Disallows closing tags for void elements, such as `<input>` and `<img>` |
|
|
192
193
|
|
|
193
194
|
You are more than welcome to contribute with us! Please check the [contribute section][contribute-docs].
|
|
194
195
|
|
|
@@ -235,6 +236,7 @@ This project was conceived by its author without any financial support, with the
|
|
|
235
236
|
[disallow-tags-readme]: <docs/rules/disallow-tags.md>
|
|
236
237
|
[enforce-security-readme]: <docs/rules/enforce-security.md>
|
|
237
238
|
[no-redundant-context-readme]: <docs/rules/no-redundant-context.md>
|
|
239
|
+
[strict-void-elements-readme]: <docs/rules/strict-void-elements.md>
|
|
238
240
|
|
|
239
241
|
[api-docs]: <docs/api.md>
|
|
240
242
|
[cli-docs]: <docs/cli.md>
|
package/package.json
CHANGED
package/src/IsmlLinter.js
CHANGED
|
@@ -101,12 +101,12 @@ const getEmptyResult = () => {
|
|
|
101
101
|
};
|
|
102
102
|
};
|
|
103
103
|
|
|
104
|
-
const
|
|
104
|
+
const parseAndPossiblyFixTemplate = (templatePath, data, content, templateName) => {
|
|
105
105
|
const formattedTemplatePath = GeneralUtils.formatTemplatePath(templatePath);
|
|
106
106
|
const templateResults = getEmptyResult();
|
|
107
107
|
|
|
108
108
|
try {
|
|
109
|
-
const parseResult = RuleUtils.
|
|
109
|
+
const parseResult = RuleUtils.parseAndPossiblyFixTemplate(templatePath, data, content, templateName);
|
|
110
110
|
|
|
111
111
|
if (parseResult.fixed) {
|
|
112
112
|
templateResults.templatesFixed++;
|
|
@@ -232,7 +232,7 @@ Linter.run = (pathData, content, data = {}) => {
|
|
|
232
232
|
const isIgnored = FileUtils.isIgnored(templatePath);
|
|
233
233
|
|
|
234
234
|
if (!isIgnored) {
|
|
235
|
-
const templateResults =
|
|
235
|
+
const templateResults = parseAndPossiblyFixTemplate(templatePath, data, content, templateName);
|
|
236
236
|
|
|
237
237
|
finalResult = merge(finalResult, templateResults);
|
|
238
238
|
}
|
|
@@ -149,6 +149,7 @@ class IsmlNode {
|
|
|
149
149
|
newNode.isEmbeddedNode = this.isEmbeddedNode;
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
+
getChild(number) { return this.children[number]; }
|
|
152
153
|
getLastChild() { return this.children[this.children.length - 1]; }
|
|
153
154
|
getChildrenQty() { return this.children.length; }
|
|
154
155
|
hasChildren() { return this.children.length > 0; }
|
|
@@ -136,7 +136,7 @@ const parseNextElement = state => {
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
state.elementList.push(newElement);
|
|
139
|
-
|
|
139
|
+
|
|
140
140
|
if (newElement.type === 'htmlTag' && newElement.value.indexOf('<isif') >= 0 && newElement.value.indexOf('</isif') < 0) {
|
|
141
141
|
throw ExceptionUtils.invalidNestedIsifError(
|
|
142
142
|
newElement.tagType,
|
|
@@ -110,14 +110,8 @@ const parseContainerElements = (element, currentParent, newNode, templatePath) =
|
|
|
110
110
|
|
|
111
111
|
const parseNonContainerElements = (element, currentParent, newNode, templatePath) => {
|
|
112
112
|
if (element.isSelfClosing) {
|
|
113
|
-
if (element.isClosingTag
|
|
114
|
-
|
|
115
|
-
element.tagType,
|
|
116
|
-
element.lineNumber,
|
|
117
|
-
element.globalPos,
|
|
118
|
-
element.value.trim().length,
|
|
119
|
-
templatePath
|
|
120
|
-
);
|
|
113
|
+
if (element.isClosingTag && element.isVoidElement) {
|
|
114
|
+
currentParent.getLastChild().setTail(element.value, element.lineNumber, element.columnNumber, element.globalPos);
|
|
121
115
|
} else {
|
|
122
116
|
currentParent.addChild(newNode);
|
|
123
117
|
}
|
package/src/publicApi.js
CHANGED
|
@@ -14,8 +14,23 @@ module.exports = {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
linterResult = IsmlLinter.run(path, content);
|
|
17
|
+
|
|
17
18
|
return linterResult;
|
|
18
19
|
},
|
|
20
|
+
fix : (path, content, config) => {
|
|
21
|
+
let autofixConfig = config;
|
|
22
|
+
|
|
23
|
+
if (config) {
|
|
24
|
+
autofixConfig.autoFix = true;
|
|
25
|
+
IsmlLinter.setConfig(autofixConfig);
|
|
26
|
+
} else {
|
|
27
|
+
autofixConfig = IsmlLinter.getConfig();
|
|
28
|
+
autofixConfig.autoFix = true;
|
|
29
|
+
IsmlLinter.setConfig(autofixConfig);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return IsmlLinter.run(path, content, autofixConfig);
|
|
33
|
+
},
|
|
19
34
|
printResults : () => ConsoleUtils.displayOccurrenceList(linterResult),
|
|
20
35
|
build : path => Builder.run(path),
|
|
21
36
|
|
package/src/rules/tree/indent.js
CHANGED
|
@@ -161,8 +161,14 @@ Rule.isQuoteClosingCharBroken = function(node) {
|
|
|
161
161
|
'';
|
|
162
162
|
|
|
163
163
|
if (message) {
|
|
164
|
+
const line = node
|
|
165
|
+
.getRoot()
|
|
166
|
+
.toString()
|
|
167
|
+
.split(Constants.EOL)[lineNumber - 1];
|
|
168
|
+
|
|
164
169
|
result.push({
|
|
165
170
|
quoteChar : attribute.quoteChar,
|
|
171
|
+
line : line,
|
|
166
172
|
lineNumber : lineNumber,
|
|
167
173
|
columnNumber : columnNumber,
|
|
168
174
|
globalPos : globalPos,
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const TreeRulePrototype = require('../prototypes/TreeRulePrototype');
|
|
2
|
+
|
|
3
|
+
const ruleId = require('path').basename(__filename).slice(0, -3);
|
|
4
|
+
const description = 'This is a void element, and as such, should not have a corresponding closing tag';
|
|
5
|
+
|
|
6
|
+
const Rule = Object.create(TreeRulePrototype);
|
|
7
|
+
|
|
8
|
+
Rule.init(ruleId, description);
|
|
9
|
+
|
|
10
|
+
Rule.isBroken = function(node) {
|
|
11
|
+
return node.isVoidElement() && node.tail.length > 0;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
Rule.check = function(node, data) {
|
|
15
|
+
|
|
16
|
+
const ruleConfig = this.getConfigs();
|
|
17
|
+
let occurrenceList = [];
|
|
18
|
+
|
|
19
|
+
occurrenceList = this.checkChildren(node, data);
|
|
20
|
+
|
|
21
|
+
if (this.isBroken(node)) {
|
|
22
|
+
const error = this.getError(
|
|
23
|
+
node.tail.trim(),
|
|
24
|
+
node.tailLineNumber,
|
|
25
|
+
node.tailColumnNumber,
|
|
26
|
+
node.tailGlobalPos,
|
|
27
|
+
node.tail.trim().length,
|
|
28
|
+
`"<${node.getType()}>" is a void element, and as such, should not have a corresponding closing tag`
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
occurrenceList.push(error);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return this.return(node, occurrenceList, ruleConfig);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
Rule.getFixedContent = node => {
|
|
38
|
+
|
|
39
|
+
if (node.isVoidElement()) {
|
|
40
|
+
node.setTail('', null, null, null);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return node.toString();
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
module.exports = Rule;
|
package/src/util/ConfigUtils.js
CHANGED
|
@@ -158,7 +158,7 @@ const existEslintConfigFile = () => {
|
|
|
158
158
|
FileUtils.fileExists(Constants.eslintConfigFilePathList[2]);
|
|
159
159
|
};
|
|
160
160
|
|
|
161
|
-
const isTestEnv = () => process.env.NODE_ENV === Constants.ENV_TEST;
|
|
161
|
+
const isTestEnv = () => process.env.NODE_ENV === Constants.ENV_TEST && !global.isSimulatingProductionEnvironment;
|
|
162
162
|
|
|
163
163
|
const setLocalConfig = configParam => {
|
|
164
164
|
if (isTestEnv()) {
|
package/src/util/RuleUtils.js
CHANGED
|
@@ -64,7 +64,7 @@ const checkCustomTag = tag => {
|
|
|
64
64
|
}
|
|
65
65
|
};
|
|
66
66
|
|
|
67
|
-
const
|
|
67
|
+
const fixTemplateOrReportIssues = (config, ruleResult, templatePath, templateResults, rule) => {
|
|
68
68
|
if (config.autoFix && ruleResult.fixedContent) {
|
|
69
69
|
fs.writeFileSync(templatePath, ruleResult.fixedContent);
|
|
70
70
|
templateResults.fixed = true;
|
|
@@ -78,7 +78,7 @@ const applyRuleResult = (config, ruleResult, templatePath, templateResults, rule
|
|
|
78
78
|
}
|
|
79
79
|
};
|
|
80
80
|
|
|
81
|
-
const
|
|
81
|
+
const fixTemplateOrReportIssuesForRuleList = (ruleArray, templatePath, root, config, data) => {
|
|
82
82
|
const templateResults = {
|
|
83
83
|
fixed : false,
|
|
84
84
|
errors : {},
|
|
@@ -92,8 +92,9 @@ const applyRuleOnTemplate = (ruleArray, templatePath, root, config, data) => {
|
|
|
92
92
|
if (!rule.shouldIgnore(templatePath)) {
|
|
93
93
|
try {
|
|
94
94
|
ConsoleUtils.displayVerboseMessage(`Applying "${rule.id}" rule`, 1);
|
|
95
|
-
const ruleResults
|
|
96
|
-
|
|
95
|
+
const ruleResults = rule.check(root, templateResults.data);
|
|
96
|
+
templateResults.finalContent = ruleResults.fixedContent;
|
|
97
|
+
fixTemplateOrReportIssues(config, ruleResults, templatePath, templateResults, rule);
|
|
97
98
|
|
|
98
99
|
} catch (error) {
|
|
99
100
|
throw ExceptionUtils.ruleApplianceError(rule, error, templatePath);
|
|
@@ -111,10 +112,10 @@ const findNodeOfType = (node, type) => {
|
|
|
111
112
|
if (child.isOfType(type)) {
|
|
112
113
|
result = child;
|
|
113
114
|
return true;
|
|
114
|
-
} else {
|
|
115
|
-
result = findNodeOfType(child, type) || result;
|
|
116
115
|
}
|
|
117
116
|
|
|
117
|
+
result = findNodeOfType(child, type) || result;
|
|
118
|
+
|
|
118
119
|
return false;
|
|
119
120
|
});
|
|
120
121
|
|
|
@@ -169,7 +170,7 @@ const checkFileName = (filename, templateContent) => {
|
|
|
169
170
|
return templateResults;
|
|
170
171
|
};
|
|
171
172
|
|
|
172
|
-
const
|
|
173
|
+
const checkAndPossiblyFixTreeRules = (templatePath, templateContent, config, data) => {
|
|
173
174
|
if (!config.disableTreeParse) {
|
|
174
175
|
ConsoleUtils.displayVerboseMessage(`Building tree for "${templatePath}"`, 1);
|
|
175
176
|
const tree = TreeBuilder.build(templatePath, templateContent);
|
|
@@ -180,7 +181,7 @@ const checkTreeRules = (templatePath, templateContent, config, data) => {
|
|
|
180
181
|
|
|
181
182
|
const ruleArray = getEnabledTreeRules();
|
|
182
183
|
|
|
183
|
-
return
|
|
184
|
+
return fixTemplateOrReportIssuesForRuleList(
|
|
184
185
|
ruleArray,
|
|
185
186
|
templatePath,
|
|
186
187
|
tree.rootNode,
|
|
@@ -189,10 +190,10 @@ const checkTreeRules = (templatePath, templateContent, config, data) => {
|
|
|
189
190
|
}
|
|
190
191
|
};
|
|
191
192
|
|
|
192
|
-
const
|
|
193
|
+
const checkAndPossiblyFixLineByLineRules = (templatePath, templateContent, config, data) => {
|
|
193
194
|
const ruleArray = getEnabledLineRules();
|
|
194
195
|
|
|
195
|
-
return
|
|
196
|
+
return fixTemplateOrReportIssuesForRuleList(
|
|
196
197
|
ruleArray,
|
|
197
198
|
templatePath,
|
|
198
199
|
templateContent,
|
|
@@ -221,12 +222,12 @@ const checkCustomModules = () => {
|
|
|
221
222
|
return moduleResults;
|
|
222
223
|
};
|
|
223
224
|
|
|
224
|
-
const
|
|
225
|
+
const parseAndPossiblyFixTemplate = (templatePath, data, content = '', templateName = '') => {
|
|
225
226
|
ConsoleUtils.displayVerboseMessage(`\nChecking "${templatePath}" template`);
|
|
226
227
|
const config = ConfigUtils.load();
|
|
227
228
|
const templateContent = GeneralUtils.toLF(content || fs.readFileSync(templatePath, 'utf-8'));
|
|
228
|
-
const lineResults =
|
|
229
|
-
const treeResults =
|
|
229
|
+
const lineResults = checkAndPossiblyFixLineByLineRules(templatePath, templateContent, config, data);
|
|
230
|
+
const treeResults = checkAndPossiblyFixTreeRules(templatePath, lineResults.finalContent, config, data) || { errors : [] };
|
|
230
231
|
const filenameResults = checkFileName(templateName, templateContent);
|
|
231
232
|
|
|
232
233
|
return {
|
|
@@ -289,7 +290,7 @@ const getEnabledTreeRules = () => {
|
|
|
289
290
|
module.exports.getAllLineRules = () => lineByLineRules;
|
|
290
291
|
module.exports.findNodeOfType = findNodeOfType;
|
|
291
292
|
module.exports.isTypeAmongTheFirstElements = isTypeAmongTheFirstElements;
|
|
292
|
-
module.exports.
|
|
293
|
+
module.exports.parseAndPossiblyFixTemplate = parseAndPossiblyFixTemplate;
|
|
293
294
|
module.exports.checkCustomModules = checkCustomModules;
|
|
294
295
|
module.exports.getAvailableRulesQty = getAvailableRulesQty;
|
|
295
296
|
module.exports.getLevelGroup = getLevelGroup;
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
===========================================================================
|
|
7
7
|
**/
|
|
8
8
|
|
|
9
|
-
const path = require('path');
|
|
10
9
|
const fs = require('fs');
|
|
11
10
|
const Constants = require('../Constants');
|
|
12
11
|
const TreeBuilder = require('../isml_tree/TreeBuilder');
|
|
@@ -38,7 +37,7 @@ const checkCustomTag = tag => {
|
|
|
38
37
|
}
|
|
39
38
|
};
|
|
40
39
|
|
|
41
|
-
const
|
|
40
|
+
const fixTemplateOrReportIssues = (config, ruleResult, templatePath, templateResults, rule) => {
|
|
42
41
|
if (config.autoFix && ruleResult.fixedContent) {
|
|
43
42
|
fs.writeFileSync(templatePath, ruleResult.fixedContent);
|
|
44
43
|
templateResults.fixed = true;
|
|
@@ -49,7 +48,7 @@ const applyRuleResult = (config, ruleResult, templatePath, templateResults, rule
|
|
|
49
48
|
}
|
|
50
49
|
};
|
|
51
50
|
|
|
52
|
-
const
|
|
51
|
+
const fixTemplateOrReportIssuesForRuleList = (ruleArray, templatePath, root, config) => {
|
|
53
52
|
const templateResults = {
|
|
54
53
|
fixed : false,
|
|
55
54
|
errors : {}
|
|
@@ -59,7 +58,7 @@ const applyRuleOnTemplate = (ruleArray, templatePath, root, config) => {
|
|
|
59
58
|
const rule = ruleArray[i];
|
|
60
59
|
if (!rule.shouldIgnore(templatePath)) {
|
|
61
60
|
const ruleResults = rule.check(root, templateResults.data);
|
|
62
|
-
|
|
61
|
+
fixTemplateOrReportIssues(config, ruleResults, templatePath, templateResults, rule);
|
|
63
62
|
}
|
|
64
63
|
}
|
|
65
64
|
|
|
@@ -130,7 +129,7 @@ const checkFileName = (filename, templateContent) => {
|
|
|
130
129
|
return templateResults;
|
|
131
130
|
};
|
|
132
131
|
|
|
133
|
-
const
|
|
132
|
+
const checkAndPossiblyFixTreeRules = (templatePath, templateContent, config) => {
|
|
134
133
|
if (!config.disableTreeParse) {
|
|
135
134
|
const tree = TreeBuilder.build(templatePath, templateContent);
|
|
136
135
|
|
|
@@ -140,7 +139,7 @@ const checkTreeRules = (templatePath, templateContent, config) => {
|
|
|
140
139
|
|
|
141
140
|
const ruleArray = getEnabledTreeRules();
|
|
142
141
|
|
|
143
|
-
return
|
|
142
|
+
return fixTemplateOrReportIssuesForRuleList(
|
|
144
143
|
ruleArray,
|
|
145
144
|
templatePath,
|
|
146
145
|
tree.rootNode,
|
|
@@ -148,10 +147,10 @@ const checkTreeRules = (templatePath, templateContent, config) => {
|
|
|
148
147
|
}
|
|
149
148
|
};
|
|
150
149
|
|
|
151
|
-
const
|
|
150
|
+
const checkAndPossiblyFixLineByLineRules = (templatePath, templateContent, config) => {
|
|
152
151
|
const ruleArray = getEnabledLineRules();
|
|
153
152
|
|
|
154
|
-
return
|
|
153
|
+
return fixTemplateOrReportIssuesForRuleList(
|
|
155
154
|
ruleArray,
|
|
156
155
|
templatePath,
|
|
157
156
|
templateContent,
|
|
@@ -176,11 +175,11 @@ const checkCustomModules = () => {
|
|
|
176
175
|
return moduleResults;
|
|
177
176
|
};
|
|
178
177
|
|
|
179
|
-
const
|
|
178
|
+
const parseAndPossiblyFixTemplate = (templatePath, content, templateName) => {
|
|
180
179
|
const config = ConfigUtils.load();
|
|
181
180
|
const templateContent = content || fs.readFileSync(templatePath, 'utf-8');
|
|
182
|
-
const lineResults =
|
|
183
|
-
const treeResults =
|
|
181
|
+
const lineResults = checkAndPossiblyFixLineByLineRules(templatePath, templateContent, config);
|
|
182
|
+
const treeResults = checkAndPossiblyFixTreeRules(templatePath, templateContent, config) || { errors : [] };
|
|
184
183
|
const filenameResults = checkFileName(templateName, templateContent);
|
|
185
184
|
|
|
186
185
|
return {
|
|
@@ -227,6 +226,6 @@ const getEnabledTreeRules = () => {
|
|
|
227
226
|
module.exports.getAllLineRules = () => lineByLineRules;
|
|
228
227
|
module.exports.findNodeOfType = findNodeOfType;
|
|
229
228
|
module.exports.isTypeAmongTheFirstElements = isTypeAmongTheFirstElements;
|
|
230
|
-
module.exports.
|
|
229
|
+
module.exports.parseAndPossiblyFixTemplate = parseAndPossiblyFixTemplate;
|
|
231
230
|
module.exports.checkCustomModules = checkCustomModules;
|
|
232
231
|
module.exports.getAvailableRulesQty = getAvailableRulesQty;
|