npm-groovy-lint 9.4.0 → 10.0.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 +41 -1
- package/README.md +54 -28
- package/lib/.groovylintrc-all.json +0 -1
- package/lib/.groovylintrc-format.json +2 -0
- package/lib/codenarc-caller.js +7 -3
- package/lib/codenarc-factory.js +76 -14
- package/lib/example/RuleSet-All.groovy +413 -417
- package/lib/example/SampleFileSmall.groovy +3 -3
- package/lib/example/SampleFileSmallFixed.txt +4 -4
- package/lib/example/SampleFileSmallFormatted.txt +4 -4
- package/lib/groovy-lint-rules.js +2 -0
- package/lib/groovy-lint.js +7 -14
- package/lib/java/CodeNarc-3.1.0.jar +0 -0
- package/lib/java/CodeNarcServer.jar +0 -0
- package/lib/java/GMetrics-2.1.0.jar +0 -0
- package/lib/java/{log4j-api-2.17.1.jar → log4j-api-2.18.0.jar} +0 -0
- package/lib/java/{log4j-core-2.17.1.jar → log4j-core-2.18.0.jar} +0 -0
- package/lib/java/{log4j-slf4j-impl-2.17.1.jar → log4j-slf4j-impl-2.18.0.jar} +0 -0
- package/lib/options.js +30 -15
- package/lib/output.js +5 -6
- package/lib/rules/DuplicateNumberLiteral.js +21 -0
- package/lib/rules/DuplicateStringLiteral.js +21 -0
- package/lib/rules/MethodParameterTypeRequired.js +21 -0
- package/lib/rules/MethodReturnTypeRequired.js +21 -0
- package/lib/rules/MisorderedStaticImports.js +2 -2
- package/lib/rules/NoDef.js +14 -0
- package/lib/rules/SimpleDateFormatMissingLocale.js +14 -0
- package/lib/rules/SpaceAfterMethodCallName.js +30 -0
- package/lib/rules/SpaceInsideParentheses.js +73 -0
- package/lib/rules/UnnecessaryPublicModifier.js +13 -0
- package/lib/rules/UnusedImport.js +7 -1
- package/lib/rules/VariableTypeRequired.js +36 -0
- package/lib/utils.js +15 -0
- package/package.json +5 -9
- package/lib/java/CodeNarc-2.2.0.jar +0 -0
- package/lib/java/gmetrics-1.1.jar +0 -0
|
@@ -3,14 +3,14 @@ import groovy.json.*
|
|
|
3
3
|
import groovy.time.TimeCategory
|
|
4
4
|
|
|
5
5
|
def returnCode = 0
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
Exception eThrow = null ;
|
|
7
|
+
try {
|
|
8
8
|
initialize(args) ;
|
|
9
9
|
} catch (Exception e){
|
|
10
10
|
eThrow = e ;
|
|
11
11
|
returnCode = 1
|
|
12
12
|
}
|
|
13
|
-
|
|
13
|
+
if (eThrow == null){
|
|
14
14
|
return 0 ;
|
|
15
15
|
}
|
|
16
16
|
else {
|
|
@@ -27,14 +27,14 @@ def initialize(args3) { //
|
|
|
27
27
|
|
|
28
28
|
class TestExecutor {
|
|
29
29
|
|
|
30
|
-
public TestExecutor(
|
|
30
|
+
public TestExecutor(args2) {
|
|
31
31
|
this.testExternalGlobalProps()
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
public testExternalGlobalProps() {
|
|
35
|
-
Utils.printlnLog(
|
|
35
|
+
Utils.printlnLog('########## testExternalGlobalProps')
|
|
36
36
|
def globalKeyName = new SecureRandom().with { (1..9).collect { (('a'..'z')).join()[ nextInt((('a'..'z')).join().length())] }.join() }
|
|
37
|
-
Utils.printlnLog(
|
|
37
|
+
Utils.printlnLog("Generated random key: ${globalKeyName}")
|
|
38
38
|
Utils.setExternalValue(globalKeyName , 'lelama' , 'nul')
|
|
39
39
|
def storedValue = Utils.getExternalValue(globalKeyName , 'lelama')
|
|
40
40
|
assert storedValue == 'nul' , 'Error in global prop key storage/ retrieval (1)'
|
|
@@ -43,7 +43,7 @@ class TestExecutor {
|
|
|
43
43
|
assert storedValue2 == 'nul2' , 'Error in global prop key storage/ retrieval (2)'
|
|
44
44
|
def storedValueBack = Utils.getExternalValue(globalKeyName , 'lelama')
|
|
45
45
|
assert storedValueBack == 'nul' , 'Error in global prop key storage/ retrieval (3)'
|
|
46
|
-
Utils.printlnLog(
|
|
46
|
+
Utils.printlnLog(Utils.getExternalValue(globalKeyName))
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
}
|
|
@@ -28,14 +28,14 @@ def initialize(args3) { //
|
|
|
28
28
|
|
|
29
29
|
class TestExecutor {
|
|
30
30
|
|
|
31
|
-
public TestExecutor(
|
|
31
|
+
public TestExecutor(args2) {
|
|
32
32
|
this.testExternalGlobalProps()
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
public testExternalGlobalProps() {
|
|
36
|
-
Utils.printlnLog(
|
|
36
|
+
Utils.printlnLog('########## testExternalGlobalProps')
|
|
37
37
|
def globalKeyName = new Random().with { (1..9).collect { (('a'..'z')).join()[ nextInt((('a'..'z')).join().length())] }.join() }
|
|
38
|
-
Utils.printlnLog(
|
|
38
|
+
Utils.printlnLog("Generated random key: ${globalKeyName}")
|
|
39
39
|
Utils.setExternalValue(globalKeyName , 'lelama' , 'nul')
|
|
40
40
|
def storedValue = Utils.getExternalValue(globalKeyName , 'lelama')
|
|
41
41
|
assert storedValue == 'nul' , 'Error in global prop key storage/ retrieval (1)'
|
|
@@ -44,7 +44,7 @@ class TestExecutor {
|
|
|
44
44
|
assert storedValue2 == 'nul2' , 'Error in global prop key storage/ retrieval (2)'
|
|
45
45
|
def storedValueBack = Utils.getExternalValue(globalKeyName , 'lelama')
|
|
46
46
|
assert storedValueBack == 'nul' , 'Error in global prop key storage/ retrieval (3)'
|
|
47
|
-
Utils.printlnLog(
|
|
47
|
+
Utils.printlnLog(Utils.getExternalValue(globalKeyName))
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
}
|
package/lib/groovy-lint-rules.js
CHANGED
|
@@ -105,6 +105,7 @@ const rulesFixPriorityOrder = [
|
|
|
105
105
|
"SpaceBeforeOpeningBrace",
|
|
106
106
|
"SpaceAfterOpeningBrace",
|
|
107
107
|
"SpaceAfterCatch",
|
|
108
|
+
"SpaceAfterMethodCallName",
|
|
108
109
|
"SpaceAfterSwitch",
|
|
109
110
|
"SpaceAfterWhile",
|
|
110
111
|
"SpaceAroundOperator",
|
|
@@ -114,6 +115,7 @@ const rulesFixPriorityOrder = [
|
|
|
114
115
|
"SpaceAfterIf",
|
|
115
116
|
"SpaceAfterSwitch",
|
|
116
117
|
"SpaceBeforeClosingBrace",
|
|
118
|
+
"SpaceInsideParentheses",
|
|
117
119
|
"UnnecessaryDefInFieldDeclaration",
|
|
118
120
|
"UnnecessaryDefInMethodDeclaration",
|
|
119
121
|
"UnnecessaryDefInVariableDeclaration",
|
package/lib/groovy-lint.js
CHANGED
|
@@ -10,7 +10,7 @@ const { NPM_GROOVY_LINT_CONSTANTS, loadConfig, getConfigFileName } = require("./
|
|
|
10
10
|
const optionsDefinition = require("./options");
|
|
11
11
|
const { computeStats, processOutput } = require("./output.js");
|
|
12
12
|
const { recordAnonymousEvent } = require("./analytics.js");
|
|
13
|
-
const { getSourceLines, isErrorInLogLevelScope } = require("./utils");
|
|
13
|
+
const { getNpmGroovyLintVersion, getSourceLines, isErrorInLogLevelScope } = require("./utils");
|
|
14
14
|
|
|
15
15
|
class NpmGroovyLint {
|
|
16
16
|
"use strict";
|
|
@@ -33,6 +33,7 @@ class NpmGroovyLint {
|
|
|
33
33
|
codeNarcStdErr;
|
|
34
34
|
codeNarcJsonResult;
|
|
35
35
|
fileList;
|
|
36
|
+
inputFileList;
|
|
36
37
|
parseErrors = [];
|
|
37
38
|
|
|
38
39
|
// npm-groovy-lint
|
|
@@ -161,7 +162,7 @@ class NpmGroovyLint {
|
|
|
161
162
|
}
|
|
162
163
|
|
|
163
164
|
// Manage anonymous stats
|
|
164
|
-
if (["initialCall", "index"].includes(this.origin) && this.options.insight
|
|
165
|
+
if (["initialCall", "index"].includes(this.origin) && this.options.insight === true) {
|
|
165
166
|
this.startElapse = performance.now();
|
|
166
167
|
}
|
|
167
168
|
|
|
@@ -179,16 +180,7 @@ class NpmGroovyLint {
|
|
|
179
180
|
|
|
180
181
|
// Show version
|
|
181
182
|
if (this.options.version) {
|
|
182
|
-
|
|
183
|
-
if (!v) {
|
|
184
|
-
try {
|
|
185
|
-
const FindPackageJson = require("find-package-json");
|
|
186
|
-
const finder = FindPackageJson(__dirname);
|
|
187
|
-
v = finder.next().value.version;
|
|
188
|
-
} catch {
|
|
189
|
-
v = "error";
|
|
190
|
-
}
|
|
191
|
-
}
|
|
183
|
+
const v = getNpmGroovyLintVersion();
|
|
192
184
|
|
|
193
185
|
const codeNarcVersionLinter = await new NpmGroovyLint([process.execPath, "", "--codenarcargs", "-version"], {}).run();
|
|
194
186
|
const codeNarcVersionLines = [(await getSourceLines(codeNarcVersionLinter.codeNarcStdOut))[0]];
|
|
@@ -238,7 +230,8 @@ class NpmGroovyLint {
|
|
|
238
230
|
codeNarcBaseDir: this.codeNarcBaseDir,
|
|
239
231
|
codeNarcIncludes: this.codeNarcIncludes,
|
|
240
232
|
codeNarcExcludes: this.codeNarcExcludes,
|
|
241
|
-
onlyCodeNarc: this.onlyCodeNarc
|
|
233
|
+
onlyCodeNarc: this.onlyCodeNarc,
|
|
234
|
+
inputFileList: this.inputFileList
|
|
242
235
|
});
|
|
243
236
|
if (!this.options.noserver) {
|
|
244
237
|
serverCallResult = await codeNarcCaller.callCodeNarcServer();
|
|
@@ -304,7 +297,7 @@ class NpmGroovyLint {
|
|
|
304
297
|
}
|
|
305
298
|
|
|
306
299
|
// Manage anonymous usage stats (except if current lint has been cancelled by a duplicate call)
|
|
307
|
-
if (this.startElapse && this.options.insight
|
|
300
|
+
if (this.startElapse && this.options.insight === true && this.status !== 9) {
|
|
308
301
|
const elapsedTimeMs = parseInt(performance.now() - this.startElapse);
|
|
309
302
|
const callerKey = this.origin === "index" ? "cli" : "module";
|
|
310
303
|
const actionKey = this.options.format ? "format" : this.options.fix ? "fix" : "lint";
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/lib/options.js
CHANGED
|
@@ -24,19 +24,9 @@ module.exports = optionator({
|
|
|
24
24
|
},
|
|
25
25
|
options: [
|
|
26
26
|
{
|
|
27
|
-
option: "
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
default: ".",
|
|
31
|
-
description: "Directory containing the files to lint (default: current directory)",
|
|
32
|
-
example: ["./path/to/my/groovy/files"]
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
option: "files",
|
|
36
|
-
alias: "f",
|
|
37
|
-
type: "String",
|
|
38
|
-
description: "Comma-separated list of Ant-style file patterns specifying files that must be included",
|
|
39
|
-
example: ["**/Jenkinsfile", "**/*.groovy", "**/*.gradle"]
|
|
27
|
+
option: "ext",
|
|
28
|
+
type: "[String]",
|
|
29
|
+
description: "Specify Groovy file extensions"
|
|
40
30
|
},
|
|
41
31
|
{
|
|
42
32
|
option: "source",
|
|
@@ -120,7 +110,16 @@ module.exports = optionator({
|
|
|
120
110
|
type: "String",
|
|
121
111
|
default: "txt",
|
|
122
112
|
description: "Output format (txt,json,sarif,html,xml), or path to a file with one of these extensions",
|
|
123
|
-
example: [
|
|
113
|
+
example: [
|
|
114
|
+
"txt",
|
|
115
|
+
"json",
|
|
116
|
+
"sarif",
|
|
117
|
+
"./logs/myLintResults.txt",
|
|
118
|
+
"./logs/myLintResults.json",
|
|
119
|
+
"./logs/myLintResults.sarif",
|
|
120
|
+
"./logs/myLintResults.html",
|
|
121
|
+
"./logs/myLintResults.xml"
|
|
122
|
+
]
|
|
124
123
|
},
|
|
125
124
|
{
|
|
126
125
|
option: "loglevel",
|
|
@@ -221,8 +220,9 @@ module.exports = optionator({
|
|
|
221
220
|
{
|
|
222
221
|
option: "insight",
|
|
223
222
|
type: "Boolean",
|
|
223
|
+
default: false,
|
|
224
224
|
description:
|
|
225
|
-
"npm-groovy-lint collects anonymous usage statistics using package https://www.npmjs.com/package/insight. If you
|
|
225
|
+
"npm-groovy-lint collects anonymous usage statistics using package https://www.npmjs.com/package/insight. If you want to enable them, use --insight option"
|
|
226
226
|
},
|
|
227
227
|
{
|
|
228
228
|
option: "help",
|
|
@@ -235,6 +235,21 @@ module.exports = optionator({
|
|
|
235
235
|
alias: "v",
|
|
236
236
|
type: "Boolean",
|
|
237
237
|
description: "Show version"
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
option: "path",
|
|
241
|
+
alias: "p",
|
|
242
|
+
type: "path::String",
|
|
243
|
+
default: ".",
|
|
244
|
+
description: "(DEPRECATED) Directory containing the files to lint (default: current directory)",
|
|
245
|
+
example: ["./path/to/my/groovy/files"]
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
option: "files",
|
|
249
|
+
alias: "f",
|
|
250
|
+
type: "String",
|
|
251
|
+
description: "(DEPRECATED) Comma-separated list of Ant-style file patterns specifying files that must be included",
|
|
252
|
+
example: ["**/Jenkinsfile", "**/*.groovy", "**/*.gradle"]
|
|
238
253
|
}
|
|
239
254
|
],
|
|
240
255
|
mutuallyExclusive: [
|
package/lib/output.js
CHANGED
|
@@ -3,7 +3,7 @@ const c = require("ansi-colors");
|
|
|
3
3
|
const fse = require("fs-extra");
|
|
4
4
|
const { SarifBuilder, SarifRunBuilder, SarifResultBuilder, SarifRuleBuilder } = require("node-sarif-builder");
|
|
5
5
|
const path = require("path");
|
|
6
|
-
const { isErrorInLogLevelScope } = require("./utils");
|
|
6
|
+
const { isErrorInLogLevelScope, getNpmGroovyLintVersion } = require("./utils");
|
|
7
7
|
|
|
8
8
|
// Compute statistics for output
|
|
9
9
|
function computeStats(lintResult) {
|
|
@@ -227,7 +227,8 @@ function buildSarifResult(lintResult) {
|
|
|
227
227
|
const sarifBuilder = new SarifBuilder();
|
|
228
228
|
// SARIF Run builder
|
|
229
229
|
const sarifRunBuilder = new SarifRunBuilder().initSimple({
|
|
230
|
-
|
|
230
|
+
toolDriverName: "npm-groovy-lint",
|
|
231
|
+
toolDriverVersion: getNpmGroovyLintVersion(),
|
|
231
232
|
url: "https://nvuillam.github.io/npm-groovy-lint/"
|
|
232
233
|
});
|
|
233
234
|
// SARIF rules
|
|
@@ -249,11 +250,9 @@ function buildSarifResult(lintResult) {
|
|
|
249
250
|
level: err.severity === "info" ? "note" : err.severity, // Other values can be "warning" or "error"
|
|
250
251
|
messageText: err.msg,
|
|
251
252
|
ruleId: err.rule,
|
|
252
|
-
fileUri: process.env.SARIF_URI_ABSOLUTE
|
|
253
|
-
? "file:///" + fileNm.replace(/\\/g, "/")
|
|
254
|
-
: path.relative(process.cwd(), fileNm)
|
|
253
|
+
fileUri: process.env.SARIF_URI_ABSOLUTE ? "file:///" + fileNm.replace(/\\/g, "/") : path.relative(process.cwd(), fileNm)
|
|
255
254
|
};
|
|
256
|
-
if (err.range) {
|
|
255
|
+
if (err && err.range && err.range.start && (err.range.start.line === 0 || err.range.start.line > 0)) {
|
|
257
256
|
sarifResultInit.startLine = fixLine(err.range.start.line);
|
|
258
257
|
sarifResultInit.startColumn = fixCol(err.range.start.character);
|
|
259
258
|
sarifResultInit.endLine = fixLine(err.range.end.line);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Duplicate number literal
|
|
2
|
+
|
|
3
|
+
const { getVariableRange } = require("../utils");
|
|
4
|
+
|
|
5
|
+
const rule = {
|
|
6
|
+
variables: [
|
|
7
|
+
{
|
|
8
|
+
name: "NUMBER_LITERAL",
|
|
9
|
+
regex: /Duplicate Number Literal: (.*)/,
|
|
10
|
+
regexPos: 1
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
range: {
|
|
14
|
+
type: "function",
|
|
15
|
+
func: (errLine, errItem, evaluatedVars) => {
|
|
16
|
+
return getVariableRange(errLine, evaluatedVars, "NUMBER_LITERAL", errItem);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
module.exports = { rule };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Duplicate string literal
|
|
2
|
+
|
|
3
|
+
const { getVariableRange } = require("../utils");
|
|
4
|
+
|
|
5
|
+
const rule = {
|
|
6
|
+
variables: [
|
|
7
|
+
{
|
|
8
|
+
name: "STRING_LITERAL",
|
|
9
|
+
regex: /Duplicate String Literal: (.*)/,
|
|
10
|
+
regexPos: 1
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
range: {
|
|
14
|
+
type: "function",
|
|
15
|
+
func: (errLine, errItem, evaluatedVars) => {
|
|
16
|
+
return getVariableRange(errLine, evaluatedVars, "STRING_LITERAL", errItem);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
module.exports = { rule };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Too many methods in a class
|
|
2
|
+
|
|
3
|
+
const { getVariableRange } = require("../utils");
|
|
4
|
+
|
|
5
|
+
const rule = {
|
|
6
|
+
variables: [
|
|
7
|
+
{
|
|
8
|
+
name: "METHODNAME",
|
|
9
|
+
regex: /"(.*)" parameter of "(.*)" method is dynamically typed/,
|
|
10
|
+
regexPos: 1
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
range: {
|
|
14
|
+
type: "function",
|
|
15
|
+
func: (errLine, errItem, evaluatedVars) => {
|
|
16
|
+
return getVariableRange(errLine, evaluatedVars, "METHODNAME", errItem);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
module.exports = { rule };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Too many methods in a class
|
|
2
|
+
|
|
3
|
+
const { getVariableRange } = require("../utils");
|
|
4
|
+
|
|
5
|
+
const rule = {
|
|
6
|
+
variables: [
|
|
7
|
+
{
|
|
8
|
+
name: "METHODNAME",
|
|
9
|
+
regex: /Method "(.*)" has a dynamic return type/,
|
|
10
|
+
regexPos: 1
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
range: {
|
|
14
|
+
type: "function",
|
|
15
|
+
func: (errLine, errItem, evaluatedVars) => {
|
|
16
|
+
return getVariableRange(errLine, evaluatedVars, "METHODNAME", errItem);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
module.exports = { rule };
|
|
@@ -177,7 +177,7 @@ import after.all.does.it.work
|
|
|
177
177
|
|
|
178
178
|
// The rest of the file below ...
|
|
179
179
|
`
|
|
180
|
-
}
|
|
180
|
+
} /*,
|
|
181
181
|
{
|
|
182
182
|
sourceBefore: `
|
|
183
183
|
// Blablabla grapes
|
|
@@ -230,7 +230,7 @@ import after.all.does.it.work
|
|
|
230
230
|
|
|
231
231
|
// The rest of the file below ...
|
|
232
232
|
`
|
|
233
|
-
}
|
|
233
|
+
} */
|
|
234
234
|
]
|
|
235
235
|
};
|
|
236
236
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Simple Date Format missing locale
|
|
2
|
+
|
|
3
|
+
const { getStringRange } = require("../utils");
|
|
4
|
+
|
|
5
|
+
const rule = {
|
|
6
|
+
range: {
|
|
7
|
+
type: "function",
|
|
8
|
+
func: (errLine, errItem) => {
|
|
9
|
+
return getStringRange(errLine, "new SimpleDateFormat", errItem);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
module.exports = { rule };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Space after method call name
|
|
2
|
+
|
|
3
|
+
const { getStringRange } = require("../utils");
|
|
4
|
+
|
|
5
|
+
const rule = {
|
|
6
|
+
range: {
|
|
7
|
+
type: "function",
|
|
8
|
+
func: (errLine, errItem) => {
|
|
9
|
+
return getStringRange(errLine, " (", errItem);
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
fix: {
|
|
13
|
+
label: "Remove space after method call name",
|
|
14
|
+
type: "replaceString",
|
|
15
|
+
before: " (",
|
|
16
|
+
after: "("
|
|
17
|
+
},
|
|
18
|
+
tests: [
|
|
19
|
+
{
|
|
20
|
+
sourceBefore: `
|
|
21
|
+
Utils.printlnLog ('-----')
|
|
22
|
+
`,
|
|
23
|
+
sourceAfter: `
|
|
24
|
+
Utils.printlnLog('-----')
|
|
25
|
+
`
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
module.exports = { rule };
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// No space between parenthesis
|
|
2
|
+
|
|
3
|
+
const { getStringRange } = require("../utils");
|
|
4
|
+
|
|
5
|
+
const rule = {
|
|
6
|
+
fix: {
|
|
7
|
+
label: "Remove spaces inside parenthesis",
|
|
8
|
+
type: "function",
|
|
9
|
+
func: line => {
|
|
10
|
+
line = line.replace(/\( +/g, "(");
|
|
11
|
+
line = line.replace(/ +\)/g, ")");
|
|
12
|
+
return line;
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
tests: [
|
|
16
|
+
{
|
|
17
|
+
sourceBefore: `
|
|
18
|
+
Utils.printlnLog( Utils.getExternalValue(globalKeyName))
|
|
19
|
+
Utils.printlnLog(Utils.getExternalValue(globalKeyName) )
|
|
20
|
+
Utils.printlnLog(Utils.getExternalValue( globalKeyName) )
|
|
21
|
+
`,
|
|
22
|
+
sourceAfter: `
|
|
23
|
+
Utils.printlnLog(Utils.getExternalValue(globalKeyName))
|
|
24
|
+
Utils.printlnLog(Utils.getExternalValue(globalKeyName))
|
|
25
|
+
Utils.printlnLog(Utils.getExternalValue(globalKeyName))
|
|
26
|
+
`
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
range: {
|
|
30
|
+
type: "function",
|
|
31
|
+
func: (errLine, errItem) => {
|
|
32
|
+
let parenthesisRange = getStringRange(errLine, "( ", errItem);
|
|
33
|
+
if (parenthesisRange.start.character < 0) {
|
|
34
|
+
parenthesisRange = getStringRange(errLine, " )", errItem);
|
|
35
|
+
}
|
|
36
|
+
return parenthesisRange;
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
rangeTests: [
|
|
40
|
+
{
|
|
41
|
+
source: `
|
|
42
|
+
def res = uuuurf( "yessss")
|
|
43
|
+
`,
|
|
44
|
+
expectedRange: {
|
|
45
|
+
start: {
|
|
46
|
+
line: 2,
|
|
47
|
+
character: 16
|
|
48
|
+
},
|
|
49
|
+
end: {
|
|
50
|
+
line: 2,
|
|
51
|
+
character: 18
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
source: `
|
|
57
|
+
def res = uuuurf("yessss" )
|
|
58
|
+
`,
|
|
59
|
+
expectedRange: {
|
|
60
|
+
start: {
|
|
61
|
+
line: 2,
|
|
62
|
+
character: 25
|
|
63
|
+
},
|
|
64
|
+
end: {
|
|
65
|
+
line: 2,
|
|
66
|
+
character: 27
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
module.exports = { rule };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Variable type required
|
|
2
|
+
const { getStringRange } = require("../utils");
|
|
3
|
+
|
|
4
|
+
const rule = {
|
|
5
|
+
range: {
|
|
6
|
+
type: "function",
|
|
7
|
+
func: (errLine, errItem) => {
|
|
8
|
+
return getStringRange(errLine, "public", errItem);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
module.exports = { rule };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Unused import
|
|
2
2
|
|
|
3
|
-
const { getVariable } = require("../utils");
|
|
3
|
+
const { getVariable, getVariableRange } = require("../utils");
|
|
4
4
|
|
|
5
5
|
const rule = {
|
|
6
6
|
scope: "file",
|
|
@@ -12,6 +12,12 @@ const rule = {
|
|
|
12
12
|
regexPos: 1
|
|
13
13
|
}
|
|
14
14
|
],
|
|
15
|
+
range: {
|
|
16
|
+
type: "function",
|
|
17
|
+
func: (errLine, errItem, evaluatedVars) => {
|
|
18
|
+
return getVariableRange(errLine, evaluatedVars, "CLASSNAME", errItem);
|
|
19
|
+
}
|
|
20
|
+
},
|
|
15
21
|
fix: {
|
|
16
22
|
label: "Remove unused import",
|
|
17
23
|
type: "function",
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Variable type required
|
|
2
|
+
const { getVariableRange } = require("../utils");
|
|
3
|
+
|
|
4
|
+
const rule = {
|
|
5
|
+
variables: [
|
|
6
|
+
{
|
|
7
|
+
name: "VARIABLE_NAME",
|
|
8
|
+
regex: /The type is not specified for variable "(.*)"/
|
|
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 returnCode = 0
|
|
21
|
+
`,
|
|
22
|
+
expectedRange: {
|
|
23
|
+
start: {
|
|
24
|
+
line: 2,
|
|
25
|
+
character: 4
|
|
26
|
+
},
|
|
27
|
+
end: {
|
|
28
|
+
line: 2,
|
|
29
|
+
character: 14
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
module.exports = { rule };
|
package/lib/utils.js
CHANGED
|
@@ -394,6 +394,20 @@ function splitMulti(str, tokens) {
|
|
|
394
394
|
return str;
|
|
395
395
|
}
|
|
396
396
|
|
|
397
|
+
function getNpmGroovyLintVersion() {
|
|
398
|
+
let v = process.env.npm_package_version;
|
|
399
|
+
if (!v) {
|
|
400
|
+
try {
|
|
401
|
+
const FindPackageJson = require("find-package-json");
|
|
402
|
+
const finder = FindPackageJson(__dirname);
|
|
403
|
+
v = finder.next().value.version;
|
|
404
|
+
} catch {
|
|
405
|
+
v = "error";
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return v;
|
|
409
|
+
}
|
|
410
|
+
|
|
397
411
|
module.exports = {
|
|
398
412
|
addImport,
|
|
399
413
|
addSpaceAfterChar,
|
|
@@ -405,6 +419,7 @@ module.exports = {
|
|
|
405
419
|
findRangeBetweenStrings,
|
|
406
420
|
getIndentLength,
|
|
407
421
|
getLastStringRange,
|
|
422
|
+
getNpmGroovyLintVersion,
|
|
408
423
|
getOutOfBracesStrings,
|
|
409
424
|
getSourceLines,
|
|
410
425
|
getStringRange,
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "npm-groovy-lint",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.0.0",
|
|
4
4
|
"description": "Lint, format and auto-fix your Groovy / Jenkinsfile / Gradle files",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"lint:fix": "eslint **/*.js --fix && prettier --write \"./lib/**/*.{js,jsx
|
|
8
|
-
"groovy:run-server-from-source": "npm run dev:kill-server && groovy -cp \"lib/java/CodeNarc-
|
|
7
|
+
"lint:fix": "eslint **/*.js --fix && prettier --write \"./lib/**/*.{js,jsx}\" --tab-width 4 --print-width 150",
|
|
8
|
+
"groovy:run-server-from-source": "npm run dev:kill-server && groovy -cp \"lib/java/CodeNarc-3.1.0.jar;lib/java/groovy/lib/groovy-3.0.9.jar;lib/java/groovy/lib/groovy-templates-3.0.9.jar;lib/java/groovy/lib/groovy-xml-3.0.9.jar;lib/java/groovy/lib/groovy-json-3.0.9.jar;lib/java/groovy/lib/groovy-ant-3.0.9.jar;lib/java/groovy/lib/ant-1.10.11.jar;lib/java/groovy/lib/ant-launcher-1.10.11.jar;lib/java/slf4j-api-1.7.9.jar;lib/java/log4j-slf4j-impl-2.18.0.jar;lib/java/log4j-api-2.18.0.jar;lib/java/log4j-core-2.18.0.jar;lib/java/GMetrics-2.1.0.jar\" groovy/src/main/com/nvuillam/CodeNarcServer.groovy --server",
|
|
9
9
|
"groovy:build": "npm run dev:kill-server && groovyc -cp \"./lib/java*\" --encoding utf-8 ./groovy/src/main/com/nvuillam/CodeNarcServer.groovy -d ./tmp && cd ./tmp && jar -cvfm ./../lib/java/CodeNarcServer.jar ./../MANIFEST.txt ./com/nvuillam/*.class && cd ..",
|
|
10
10
|
"test": "npm run dev:kill-server && mocha \"test/**/*.test.js\"",
|
|
11
11
|
"test:coverage": "nyc npm run test",
|
|
@@ -58,7 +58,8 @@
|
|
|
58
58
|
"import-fresh": "^3.2.1",
|
|
59
59
|
"ip": "^1.1.5",
|
|
60
60
|
"java-caller": "^2.2.4",
|
|
61
|
-
"
|
|
61
|
+
"js-yaml": "^4.1.0",
|
|
62
|
+
"node-sarif-builder": "^2.0.1",
|
|
62
63
|
"optionator": "^0.8.3",
|
|
63
64
|
"semver": "^7.1.3",
|
|
64
65
|
"strip-json-comments": "^3.0.1",
|
|
@@ -69,11 +70,6 @@
|
|
|
69
70
|
"@babel/eslint-parser": "^7.16.3",
|
|
70
71
|
"diff": "^4.0.2",
|
|
71
72
|
"eslint": "^8.2.0",
|
|
72
|
-
"eslint-config-standard": "^16.0.3",
|
|
73
|
-
"eslint-plugin-import": "^2.25.3",
|
|
74
|
-
"eslint-plugin-node": "^11.1.0",
|
|
75
|
-
"eslint-plugin-promise": "^5.1.1",
|
|
76
|
-
"eslint-plugin-standard": "^5.0.0",
|
|
77
73
|
"mocha": "^7.0.1",
|
|
78
74
|
"nyc": "^15.1.0",
|
|
79
75
|
"prettier": "^1.19.1",
|
|
Binary file
|
|
Binary file
|