npm-groovy-lint 9.5.0 → 10.0.2

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.
Files changed (35) hide show
  1. package/CHANGELOG.md +40 -2
  2. package/README.md +29 -3
  3. package/lib/.groovylintrc-all.json +0 -1
  4. package/lib/.groovylintrc-format.json +2 -0
  5. package/lib/codenarc-caller.js +7 -3
  6. package/lib/codenarc-factory.js +103 -16
  7. package/lib/example/RuleSet-All.groovy +413 -417
  8. package/lib/example/SampleFileSmall.groovy +3 -3
  9. package/lib/example/SampleFileSmallFixed.txt +4 -4
  10. package/lib/example/SampleFileSmallFormatted.txt +4 -4
  11. package/lib/groovy-lint-rules.js +2 -0
  12. package/lib/groovy-lint.js +3 -1
  13. package/lib/index.js +5 -1
  14. package/lib/java/CodeNarc-3.1.0.jar +0 -0
  15. package/lib/java/CodeNarcServer.jar +0 -0
  16. package/lib/java/GMetrics-2.1.0.jar +0 -0
  17. package/lib/java/{log4j-api-2.17.1.jar → log4j-api-2.18.0.jar} +0 -0
  18. package/lib/java/{log4j-core-2.17.1.jar → log4j-core-2.18.0.jar} +0 -0
  19. package/lib/java/{log4j-slf4j-impl-2.17.1.jar → log4j-slf4j-impl-2.18.0.jar} +0 -0
  20. package/lib/options.js +28 -14
  21. package/lib/output.js +1 -3
  22. package/lib/rules/DuplicateNumberLiteral.js +21 -0
  23. package/lib/rules/DuplicateStringLiteral.js +21 -0
  24. package/lib/rules/MethodParameterTypeRequired.js +21 -0
  25. package/lib/rules/MisorderedStaticImports.js +2 -2
  26. package/lib/rules/NoDef.js +14 -0
  27. package/lib/rules/SimpleDateFormatMissingLocale.js +14 -0
  28. package/lib/rules/SpaceAfterMethodCallName.js +30 -0
  29. package/lib/rules/SpaceInsideParentheses.js +73 -0
  30. package/lib/rules/UnnecessaryPublicModifier.js +13 -0
  31. package/lib/rules/VariableTypeRequired.js +36 -0
  32. package/lib/utils.js +2 -2
  33. package/package.json +5 -8
  34. package/lib/java/CodeNarc-2.2.0.jar +0 -0
  35. 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
- Exception eThrow = null ;
7
- try {
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
- if (eThrow == null){
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( args2) {
30
+ public TestExecutor(args2) {
31
31
  this.testExternalGlobalProps()
32
32
  }
33
33
 
34
34
  public testExternalGlobalProps() {
35
- Utils.printlnLog( '########## testExternalGlobalProps')
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( "Generated random key: ${globalKeyName}")
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( Utils.getExternalValue(globalKeyName))
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( args2) {
31
+ public TestExecutor(args2) {
32
32
  this.testExternalGlobalProps()
33
33
  }
34
34
 
35
35
  public testExternalGlobalProps() {
36
- Utils.printlnLog( '########## testExternalGlobalProps')
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( "Generated random key: ${globalKeyName}")
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( Utils.getExternalValue(globalKeyName))
47
+ Utils.printlnLog(Utils.getExternalValue(globalKeyName))
48
48
  }
49
49
 
50
50
  }
@@ -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",
@@ -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
@@ -229,7 +230,8 @@ class NpmGroovyLint {
229
230
  codeNarcBaseDir: this.codeNarcBaseDir,
230
231
  codeNarcIncludes: this.codeNarcIncludes,
231
232
  codeNarcExcludes: this.codeNarcExcludes,
232
- onlyCodeNarc: this.onlyCodeNarc
233
+ onlyCodeNarc: this.onlyCodeNarc,
234
+ inputFileList: this.inputFileList
233
235
  });
234
236
  if (!this.options.noserver) {
235
237
  serverCallResult = await codeNarcCaller.callCodeNarcServer();
package/lib/index.js CHANGED
@@ -13,6 +13,10 @@ const linter = new NpmGroovyLint(process.argv, { origin: "index" });
13
13
  process.exitCode = linter.status;
14
14
  } catch (err) {
15
15
  console.error("Unexpected error: " + err.message + "\n" + err.stack);
16
- process.exitCode = 1;
16
+ process.exitCode = 2;
17
+ // Quit if called by CLI and not as a module
18
+ if (require.main === module) {
19
+ process.exit();
20
+ }
17
21
  }
18
22
  })();
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: "path",
28
- alias: "p",
29
- type: "path::String",
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: ["txt", "json", "sarif", "./logs/myLintResults.txt", "./logs/myLintResults.json","./logs/myLintResults.sarif", "./logs/myLintResults.html", "./logs/myLintResults.xml"]
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",
@@ -236,6 +235,21 @@ module.exports = optionator({
236
235
  alias: "v",
237
236
  type: "Boolean",
238
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"]
239
253
  }
240
254
  ],
241
255
  mutuallyExclusive: [
package/lib/output.js CHANGED
@@ -250,9 +250,7 @@ function buildSarifResult(lintResult) {
250
250
  level: err.severity === "info" ? "note" : err.severity, // Other values can be "warning" or "error"
251
251
  messageText: err.msg,
252
252
  ruleId: err.rule,
253
- fileUri: process.env.SARIF_URI_ABSOLUTE
254
- ? "file:///" + fileNm.replace(/\\/g, "/")
255
- : path.relative(process.cwd(), fileNm)
253
+ fileUri: process.env.SARIF_URI_ABSOLUTE ? "file:///" + fileNm.replace(/\\/g, "/") : path.relative(process.cwd(), fileNm)
256
254
  };
257
255
  if (err && err.range && err.range.start && (err.range.start.line === 0 || err.range.start.line > 0)) {
258
256
  sarifResultInit.startLine = fixLine(err.range.start.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 };
@@ -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
+ // No use of def
2
+
3
+ const { getStringRange } = require("../utils");
4
+
5
+ const rule = {
6
+ range: {
7
+ type: "function",
8
+ func: (errLine, errItem) => {
9
+ return getStringRange(errLine, "def", errItem);
10
+ }
11
+ }
12
+ };
13
+
14
+ module.exports = { rule };
@@ -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 };
@@ -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,7 +394,7 @@ function splitMulti(str, tokens) {
394
394
  return str;
395
395
  }
396
396
 
397
- function getNpmGroovyLintVersion(){
397
+ function getNpmGroovyLintVersion() {
398
398
  let v = process.env.npm_package_version;
399
399
  if (!v) {
400
400
  try {
@@ -405,7 +405,7 @@ function getNpmGroovyLintVersion(){
405
405
  v = "error";
406
406
  }
407
407
  }
408
- return v ;
408
+ return v;
409
409
  }
410
410
 
411
411
  module.exports = {
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "npm-groovy-lint",
3
- "version": "9.5.0",
3
+ "version": "10.0.2",
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,json}\" --tab-width 4 --print-width 150",
8
- "groovy:run-server-from-source": "npm run dev:kill-server && groovy -cp \"lib/java/CodeNarc-2.2.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.17.1.jar;lib/java/log4j-api-2.17.1.jar;lib/java/log4j-core-2.17.1.jar;lib/java/gmetrics-1.1.jar\" groovy/src/main/com/nvuillam/CodeNarcServer.groovy --server",
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",
@@ -49,6 +49,7 @@
49
49
  "axios": "^0.21.1",
50
50
  "chalk": "^4.1.2",
51
51
  "cli-progress": "^3.10.0",
52
+ "commondir": "^1.0.1",
52
53
  "debug": "^4.1.1",
53
54
  "decode-html": "^2.0.0",
54
55
  "find-java-home": "^1.1.0",
@@ -58,6 +59,7 @@
58
59
  "import-fresh": "^3.2.1",
59
60
  "ip": "^1.1.5",
60
61
  "java-caller": "^2.2.4",
62
+ "js-yaml": "^4.1.0",
61
63
  "node-sarif-builder": "^2.0.1",
62
64
  "optionator": "^0.8.3",
63
65
  "semver": "^7.1.3",
@@ -69,11 +71,6 @@
69
71
  "@babel/eslint-parser": "^7.16.3",
70
72
  "diff": "^4.0.2",
71
73
  "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
74
  "mocha": "^7.0.1",
78
75
  "nyc": "^15.1.0",
79
76
  "prettier": "^1.19.1",
Binary file
Binary file