npm-groovy-lint 10.1.0 → 11.1.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 +12 -0
- package/lib/codenarc-factory.js +8 -1
- package/lib/config.js +1 -1
- package/lib/groovy-lint.js +8 -0
- package/lib/options.js +1 -1
- package/lib/output.js +8 -3
- package/lib/rules/BlankLineBeforePackage.js +26 -0
- package/lib/rules/GStringExpressionWithinString.js +23 -0
- package/lib/rules/VariableName.js +36 -0
- package/lib/utils.js +8 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## UNRELEASED
|
|
4
4
|
|
|
5
|
+
## [11.1.0] 2022-10-31
|
|
6
|
+
|
|
7
|
+
- Provide default range when only information available is a line number ([#248](https://github.com/nvuillam/npm-groovy-lint/issues/248))
|
|
8
|
+
- New CodeNarc issues definition to calculate range in file
|
|
9
|
+
- GStringExpressionWithinString
|
|
10
|
+
- VariableName
|
|
11
|
+
|
|
12
|
+
## [11.0.0] 2022-10-07
|
|
13
|
+
|
|
14
|
+
- **BREAKING CHANGE**:`--failon` is now `ìnfo` by default, meaning exit code will be `1` if there is at least an info issue found. To have previous behaviour, use `--failon none`.
|
|
15
|
+
- Display all files in console log only if `--verbose` is used ([#243](https://github.com/nvuillam/npm-groovy-lint/issues/243))
|
|
16
|
+
|
|
5
17
|
## [10.1.0] 2022-08-15
|
|
6
18
|
|
|
7
19
|
- Allow to send groovy sources as input from stdin
|
package/lib/codenarc-factory.js
CHANGED
|
@@ -9,7 +9,7 @@ const path = require("path");
|
|
|
9
9
|
const { getConfigFileName } = require("./config.js");
|
|
10
10
|
const { collectDisabledBlocks, isFilteredError } = require("./filter.js");
|
|
11
11
|
const { getNpmGroovyLintRules } = require("./groovy-lint-rules.js");
|
|
12
|
-
const { evaluateRange, evaluateVariables, getSourceLines, normalizeNewLines } = require("./utils.js");
|
|
12
|
+
const { evaluateRange, evaluateRangeFromLine, evaluateVariables, getSourceLines, normalizeNewLines } = require("./utils.js");
|
|
13
13
|
|
|
14
14
|
////////////////////////////
|
|
15
15
|
// Build codenarc options //
|
|
@@ -325,6 +325,13 @@ async function parseCodeNarcResult(options, codeNarcBaseDir, codeNarcJsonResult,
|
|
|
325
325
|
errItem.range = range;
|
|
326
326
|
}
|
|
327
327
|
}
|
|
328
|
+
// Add unprecise range based on line when range function has not been defined on rule
|
|
329
|
+
else if (errItem.line > 0) {
|
|
330
|
+
const range = evaluateRangeFromLine(errItem, allLines);
|
|
331
|
+
if (range && range.start.character > -1) {
|
|
332
|
+
errItem.range = range;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
328
335
|
}
|
|
329
336
|
// Add in file errors
|
|
330
337
|
files[fileNm].errors.push(errItem);
|
package/lib/config.js
CHANGED
|
@@ -239,7 +239,7 @@ async function loadYAMLConfigFile(filePath) {
|
|
|
239
239
|
try {
|
|
240
240
|
// empty YAML file can be null, so always use
|
|
241
241
|
const fileContent = await readFile(filePath);
|
|
242
|
-
return yaml.
|
|
242
|
+
return yaml.load(fileContent) || {};
|
|
243
243
|
} catch (e) {
|
|
244
244
|
debug(`Error reading YAML file: ${filePath}`);
|
|
245
245
|
e.message = `Cannot read config file: ${filePath}\nError: ${e.message}`;
|
package/lib/groovy-lint.js
CHANGED
|
@@ -467,6 +467,10 @@ class NpmGroovyLint {
|
|
|
467
467
|
|
|
468
468
|
// Exit with code 1 if failon, failonerror, failonwarning or failoninfo is set
|
|
469
469
|
manageReturnCode() {
|
|
470
|
+
if (this.status > 1) {
|
|
471
|
+
// There has been a fatal error before, so there are no results
|
|
472
|
+
return ;
|
|
473
|
+
}
|
|
470
474
|
const failureLevel =
|
|
471
475
|
this.options.failon && this.options.failon !== "none"
|
|
472
476
|
? this.options.failon
|
|
@@ -480,6 +484,10 @@ class NpmGroovyLint {
|
|
|
480
484
|
if (failureLevel === "none") {
|
|
481
485
|
return;
|
|
482
486
|
}
|
|
487
|
+
if (this.lintResult.summary == null) {
|
|
488
|
+
// Special case like --codenarcargs (should not be used in thee future)
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
483
491
|
|
|
484
492
|
const errorNb = this.lintResult.summary.totalFoundErrorNumber;
|
|
485
493
|
const warningNb = this.lintResult.summary.totalFoundWarningNumber;
|
package/lib/options.js
CHANGED
|
@@ -139,7 +139,7 @@ module.exports = optionator({
|
|
|
139
139
|
option: "failon",
|
|
140
140
|
type: "String",
|
|
141
141
|
enum: ["error", "warning", "info", "none"],
|
|
142
|
-
default: "
|
|
142
|
+
default: "info",
|
|
143
143
|
description:
|
|
144
144
|
"Defines the error level where CLI will fail (return code = 1). error,warning,info or none. Every failure level includes the more critical ones.",
|
|
145
145
|
example: ["error", "warning", "info", "none"]
|
package/lib/output.js
CHANGED
|
@@ -108,11 +108,13 @@ async function processOutput(outputType, output, lintResult, options, fixer = nu
|
|
|
108
108
|
// Errors
|
|
109
109
|
for (const fileNm of Object.keys(lintResult.files)) {
|
|
110
110
|
const fileErrors = lintResult.files[fileNm].errors;
|
|
111
|
-
|
|
111
|
+
let fileOutputString = c.underline(fileNm) + "\n";
|
|
112
|
+
let showFileInOutput = false ;
|
|
112
113
|
for (const err of fileErrors) {
|
|
113
114
|
if (!isErrorInLogLevelScope(err.severity, options.loglevel)) {
|
|
114
115
|
continue;
|
|
115
116
|
}
|
|
117
|
+
showFileInOutput = true ;
|
|
116
118
|
let color = "grey";
|
|
117
119
|
switch (err.severity) {
|
|
118
120
|
case "error":
|
|
@@ -135,7 +137,7 @@ async function processOutput(outputType, output, lintResult, options, fixer = nu
|
|
|
135
137
|
}
|
|
136
138
|
}
|
|
137
139
|
// Build error output line
|
|
138
|
-
|
|
140
|
+
fileOutputString +=
|
|
139
141
|
" " +
|
|
140
142
|
err.line.toString().padEnd(4, " ") +
|
|
141
143
|
" " +
|
|
@@ -146,7 +148,10 @@ async function processOutput(outputType, output, lintResult, options, fixer = nu
|
|
|
146
148
|
err.rule.padEnd(24, " ") +
|
|
147
149
|
"\n";
|
|
148
150
|
}
|
|
149
|
-
|
|
151
|
+
fileOutputString += "\n";
|
|
152
|
+
if (showFileInOutput || options.verbose) {
|
|
153
|
+
outputString += fileOutputString ;
|
|
154
|
+
}
|
|
150
155
|
}
|
|
151
156
|
outputString += "\nnpm-groovy-lint results in " + c.bold(lintResult.summary.totalFilesLinted) + " linted files:";
|
|
152
157
|
|
|
@@ -45,6 +45,32 @@ class BuildEnv implements Serializable {
|
|
|
45
45
|
}
|
|
46
46
|
`
|
|
47
47
|
}
|
|
48
|
+
],
|
|
49
|
+
rangeTests: [
|
|
50
|
+
{
|
|
51
|
+
source: `#!/usr/bin/env groovy
|
|
52
|
+
|
|
53
|
+
package org.pdxc.devops
|
|
54
|
+
|
|
55
|
+
class BuildEnv implements Serializable {
|
|
56
|
+
private String image
|
|
57
|
+
private String tag
|
|
58
|
+
private String dockerRegistry
|
|
59
|
+
private String dockerRegistryCredsId
|
|
60
|
+
private Map envVars
|
|
61
|
+
}
|
|
62
|
+
`,
|
|
63
|
+
expectedRange: {
|
|
64
|
+
start: {
|
|
65
|
+
line: 1,
|
|
66
|
+
character: 0
|
|
67
|
+
},
|
|
68
|
+
end: {
|
|
69
|
+
line: 1,
|
|
70
|
+
character: 21
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
48
74
|
]
|
|
49
75
|
};
|
|
50
76
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// GString Expression within string
|
|
2
|
+
|
|
3
|
+
const rule = {
|
|
4
|
+
rangeTests: [
|
|
5
|
+
{
|
|
6
|
+
source: `
|
|
7
|
+
def someString = '\${SCRIPT,template=\\"mail_template_robot_results.groovy\\"}'
|
|
8
|
+
`,
|
|
9
|
+
expectedRange: {
|
|
10
|
+
start: {
|
|
11
|
+
line: 2,
|
|
12
|
+
character: 0
|
|
13
|
+
},
|
|
14
|
+
end: {
|
|
15
|
+
line: 2,
|
|
16
|
+
character: 76
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
module.exports = { rule };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Variable name invalid
|
|
2
|
+
const { getVariableRange } = require("../utils");
|
|
3
|
+
|
|
4
|
+
const rule = {
|
|
5
|
+
variables: [
|
|
6
|
+
{
|
|
7
|
+
name: "VARIABLE_NAME",
|
|
8
|
+
regex: /Variable named (.*) in (.*) does not match the pattern (.*)/
|
|
9
|
+
}
|
|
10
|
+
],
|
|
11
|
+
range: {
|
|
12
|
+
type: "function",
|
|
13
|
+
func: (errLine, errItem, evaluatedVars) => {
|
|
14
|
+
return getVariableRange(errLine, evaluatedVars, "VARIABLE_NAME", errItem);
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
rangeTests: [
|
|
18
|
+
{
|
|
19
|
+
source: `
|
|
20
|
+
def RANDOM_ID = 0
|
|
21
|
+
`,
|
|
22
|
+
expectedRange: {
|
|
23
|
+
start: {
|
|
24
|
+
line: 2,
|
|
25
|
+
character: 4
|
|
26
|
+
},
|
|
27
|
+
end: {
|
|
28
|
+
line: 2,
|
|
29
|
+
character: 13
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
module.exports = { rule };
|
package/lib/utils.js
CHANGED
|
@@ -122,6 +122,11 @@ function evaluateRange(errItem, rule, evaluatedVars, errLine, allLines) {
|
|
|
122
122
|
return range;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
// Get position to highlight in sources
|
|
126
|
+
function evaluateRangeFromLine(errItem, allLines) {
|
|
127
|
+
return getDefaultRange(allLines, errItem)
|
|
128
|
+
}
|
|
129
|
+
|
|
125
130
|
// Evaluate variables from messages
|
|
126
131
|
function evaluateVariables(variableDefs, msg) {
|
|
127
132
|
const evaluatedVars = [];
|
|
@@ -137,8 +142,8 @@ function evaluateVariables(variableDefs, msg) {
|
|
|
137
142
|
varDef.type && varDef.type === "number"
|
|
138
143
|
? parseInt(value, 10)
|
|
139
144
|
: varDef.type && varDef.type === "array"
|
|
140
|
-
|
|
141
|
-
|
|
145
|
+
? JSON.parse(value)
|
|
146
|
+
: value;
|
|
142
147
|
evaluatedVars.push({
|
|
143
148
|
name: varDef.name,
|
|
144
149
|
value: varValue
|
|
@@ -415,6 +420,7 @@ module.exports = {
|
|
|
415
420
|
containsOtherThan,
|
|
416
421
|
containsExceptInsideString,
|
|
417
422
|
evaluateRange,
|
|
423
|
+
evaluateRangeFromLine,
|
|
418
424
|
evaluateVariables,
|
|
419
425
|
findRangeBetweenStrings,
|
|
420
426
|
getIndentLength,
|