npm-groovy-lint 10.0.1 → 10.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 +17 -0
- package/README.md +62 -46
- package/lib/codenarc-factory.js +34 -10
- package/lib/groovy-lint.js +31 -13
- package/lib/output.js +7 -1
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
## UNRELEASED
|
|
4
4
|
|
|
5
|
+
## [10.1.0] 2022-08-15
|
|
6
|
+
|
|
7
|
+
- Allow to send groovy sources as input from stdin
|
|
8
|
+
- If `--format` or `--fix` option is used when source is sent as stdin, the result is output as stdout
|
|
9
|
+
|
|
10
|
+
Example: `cat path/to/my/Jenkinsfile | npm-groovy-lint --format -`
|
|
11
|
+
|
|
12
|
+
## [10.0.3] 2022-08-15
|
|
13
|
+
|
|
14
|
+
- Do not output results summary in console logs when output is json or sarif
|
|
15
|
+
- Add test methods for SARIF called by CLI
|
|
16
|
+
|
|
17
|
+
## [10.0.2] 2022-08-15
|
|
18
|
+
|
|
19
|
+
- Fix error when absolute files sent as positional arguments on a linux system ([#232](https://github.com/nvuillam/npm-groovy-lint/issues/232))
|
|
20
|
+
- Improve performances by calculating the longest command directory to send as base path to CodeNarc
|
|
21
|
+
|
|
5
22
|
## [10.0.1] 2022-08-14
|
|
6
23
|
|
|
7
24
|
- Fix error when files sent as positional arguments ([#232](https://github.com/nvuillam/npm-groovy-lint/issues/232))
|
package/README.md
CHANGED
|
@@ -43,8 +43,6 @@ Any **question**, **problem** or **enhancement request** ? Ask [**here**](https:
|
|
|
43
43
|
npm-groovy-lint [OPTIONS] [FILES|PATH|PATTERN]
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
See [examples](#example-calls)
|
|
47
|
-
|
|
48
46
|
| Parameter | Type | Description |
|
|
49
47
|
|-------------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
50
48
|
| -o<br/> --output | String | Output format (txt,json,sarif,html,xml), or path to a file with one of these extensions<br/> Default: `txt`<br/> Examples:<br/> - `"txt"`<br/> - `"json"`<br/> - `"./logs/myLintResults.txt"`<br/> - `"./logs/myLintResults.sarif"`<br/> - `"./logs/myLintResults.html"`<br/> - `"./logs/myLintResults.xml"` |
|
|
@@ -72,6 +70,68 @@ See [examples](#example-calls)
|
|
|
72
70
|
| -p<br/> --path | String | (DEPRECATED) Directory containing the files to lint<br/> Example: `./path/to/my/groovy/files` |
|
|
73
71
|
| -f<br/> --files | String | (DEPRECATED) Comma-separated list of Ant-style file patterns specifying files that must be included.<br/> Default: `"**/*.groovy,**/Jenkinsfile,**/*.gradle"`<br/>Examples:<br/> - `"**/Jenkinsfile"`<br/> - `"**/*.groovy"`<br/> - `"**/*.gradle"`<br/> - `"**/mySingleFile.groovy"` |
|
|
74
72
|
|
|
73
|
+
### Example calls
|
|
74
|
+
|
|
75
|
+
- Lint a file
|
|
76
|
+
|
|
77
|
+
```shell
|
|
78
|
+
npm-groovy-lint path/to/my/groovy/file.groovy
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
- Lint multiple files
|
|
82
|
+
|
|
83
|
+
```shell
|
|
84
|
+
npm-groovy-lint path/to/my/groovy/file.groovy path/to/my/groovy/file2.groovy path/to/my/groovy/file3.groovy
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
- Lint directory
|
|
88
|
+
|
|
89
|
+
```shell
|
|
90
|
+
npm-groovy-lint path/to/my/groovy
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
- Lint pattern
|
|
94
|
+
|
|
95
|
+
```shell
|
|
96
|
+
npm-groovy-lint path/to/my/groovy/*.groovy
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
- Lint groovy with JSON output
|
|
100
|
+
|
|
101
|
+
```shell
|
|
102
|
+
npm-groovy-lint --output json
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
- Format files
|
|
106
|
+
|
|
107
|
+
```shell
|
|
108
|
+
npm-groovy-lint --format my/path/to/file.groovy my/path/to/file2.groovy
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
- Format and fix files
|
|
112
|
+
|
|
113
|
+
```shell
|
|
114
|
+
npm-groovy-lint --fix my/path/to/file.groovy my/path/to/file2.groovy
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
- Get formatted sources in stdout from stdin
|
|
118
|
+
|
|
119
|
+
```shell
|
|
120
|
+
cat path/to/my/Jenkinsfile | npm-groovy-lint --format -
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
- Advanced config
|
|
124
|
+
|
|
125
|
+
```shell
|
|
126
|
+
npm-groovy-lint --path "./path/to/my/groovy/files" --files "**/*.groovy" --config "./config/codenarc/.groovylintrcCustom.js" --loglevel warning --output txt
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
- Lint using core CodeNarc parameters and generate HTML report file
|
|
130
|
+
|
|
131
|
+
```shell
|
|
132
|
+
npm-groovy-lint --codenarcargs -basedir="lib/example" -rulesetfiles="file:lib/example/RuleSet-Groovy.groovy" -title="TestTitleCodenarc" -maxPriority1Violations=0' -report="html:ReportTestCodenarc.html"
|
|
133
|
+
```
|
|
134
|
+
|
|
75
135
|
## Installation
|
|
76
136
|
|
|
77
137
|
```shell
|
|
@@ -145,50 +205,6 @@ OR
|
|
|
145
205
|
}
|
|
146
206
|
```
|
|
147
207
|
|
|
148
|
-
## Example calls
|
|
149
|
-
|
|
150
|
-
- Lint a file
|
|
151
|
-
|
|
152
|
-
```shell
|
|
153
|
-
npm-groovy-lint path/to/my/groovy/file.groovy
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
- Lint multiple files
|
|
157
|
-
|
|
158
|
-
```shell
|
|
159
|
-
npm-groovy-lint path/to/my/groovy/file.groovy path/to/my/groovy/file2.groovy path/to/my/groovy/file3.groovy
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
- Lint directory
|
|
163
|
-
|
|
164
|
-
```shell
|
|
165
|
-
npm-groovy-lint path/to/my/groovy
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
- Lint pattern
|
|
169
|
-
|
|
170
|
-
```shell
|
|
171
|
-
npm-groovy-lint path/to/my/groovy/*.groovy
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
- Lint groovy with JSON output
|
|
175
|
-
|
|
176
|
-
```shell
|
|
177
|
-
npm-groovy-lint --output json
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
- Advanced config
|
|
181
|
-
|
|
182
|
-
```shell
|
|
183
|
-
npm-groovy-lint --path "./path/to/my/groovy/files" --files "**/*.groovy" --config "./config/codenarc/.groovylintrcCustom.js" --loglevel warning --output txt
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
- Lint using core CodeNarc parameters and generate HTML report file
|
|
187
|
-
|
|
188
|
-
```shell
|
|
189
|
-
npm-groovy-lint --codenarcargs -basedir="lib/example" -rulesetfiles="file:lib/example/RuleSet-Groovy.groovy" -title="TestTitleCodenarc" -maxPriority1Violations=0' -report="html:ReportTestCodenarc.html"
|
|
190
|
-
```
|
|
191
|
-
|
|
192
208
|
## Disabling rules in source
|
|
193
209
|
|
|
194
210
|
You can disable rules directly by adding comment in file, using [eslint style](https://eslint.org/docs/user-guide/configuring#disabling-rules-with-inline-comments)
|
package/lib/codenarc-factory.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
const debug = require("debug")("npm-groovy-lint");
|
|
5
|
+
const commondir = require("commondir");
|
|
5
6
|
const fs = require("fs-extra");
|
|
6
7
|
const os = require("os");
|
|
7
8
|
const path = require("path");
|
|
@@ -55,8 +56,11 @@ async function prepareCodeNarcCall(options) {
|
|
|
55
56
|
|
|
56
57
|
// Define base directory
|
|
57
58
|
const baseBefore = (cnPath !== "." && cnPath.startsWith("/")) || cnPath.includes(":/") || cnPath.includes(":\\") ? "" : process.cwd() + "/";
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
const codeNarcBaseDir = positionalArgs.length > 0 ?
|
|
60
|
+
(await getCodeNarcBaseDirFromFiles(positionalArgs)) :
|
|
61
|
+
cnPath !== "." ? baseBefore + cnPath.replace(/^"(.*)"$/, "$1") :
|
|
62
|
+
process.cwd();
|
|
63
|
+
result.codeNarcBaseDir = path.resolve(codeNarcBaseDir);
|
|
60
64
|
result.codenarcArgs.push(`-basedir=${result.codeNarcBaseDir}`);
|
|
61
65
|
|
|
62
66
|
// Create ruleSet groovy file if necessary
|
|
@@ -90,17 +94,18 @@ async function prepareCodeNarcCall(options) {
|
|
|
90
94
|
if (directoryExists(resolvedPath)) {
|
|
91
95
|
finalPattern = "**/" + path.normalize(pathname.replace(/[/\\]$/u, "")).replace(/\\/gu, "/") + filePatterns;
|
|
92
96
|
}
|
|
93
|
-
//
|
|
94
|
-
if (fs.existsSync(finalPattern)) {
|
|
97
|
+
// Relative with codeNarcBaseDir
|
|
98
|
+
else if (fs.existsSync(path.join(result.codeNarcBaseDir, finalPattern))) {
|
|
95
99
|
const absolutePath = path.resolve(finalPattern).replace(/\\/gu, "/");
|
|
96
|
-
const relativePath = path.relative(process.cwd(), path.resolve(finalPattern)).replace(/\\/gu, "/");
|
|
97
100
|
fileList.push(absolutePath);
|
|
101
|
+
const relativePath = finalPattern.replace(/\\/gu, "/");
|
|
98
102
|
finalPattern = "**/" + path.normalize(relativePath.replace(/[/\\]$/u, "")).replace(/\\/gu, "/");
|
|
99
103
|
}
|
|
100
|
-
//
|
|
101
|
-
else if (fs.existsSync(
|
|
102
|
-
const
|
|
103
|
-
fileList.push(
|
|
104
|
+
// Absolute or cwd - relative path file
|
|
105
|
+
else if (fs.existsSync(finalPattern)) {
|
|
106
|
+
const absolutePath = path.resolve(finalPattern).replace(/\\/gu, "/");
|
|
107
|
+
fileList.push(absolutePath);
|
|
108
|
+
const relativePath = path.relative(result.codeNarcBaseDir, path.resolve(finalPattern)).replace(/\\/gu, "/");
|
|
104
109
|
finalPattern = "**/" + path.normalize(relativePath.replace(/[/\\]$/u, "")).replace(/\\/gu, "/");
|
|
105
110
|
}
|
|
106
111
|
// Directory or ant pattern
|
|
@@ -131,7 +136,7 @@ async function prepareCodeNarcCall(options) {
|
|
|
131
136
|
// Output
|
|
132
137
|
result.output = options.output.replace(/^"(.*)"$/, "$1");
|
|
133
138
|
if (
|
|
134
|
-
["txt", "json", "sarif", "none"].includes(result.output) ||
|
|
139
|
+
["txt", "json", "sarif", "none", "stdout"].includes(result.output) ||
|
|
135
140
|
result.output.endsWith(".txt") ||
|
|
136
141
|
result.output.endsWith(".sarif") ||
|
|
137
142
|
result.output.endsWith(".json")
|
|
@@ -174,6 +179,25 @@ async function prepareCodeNarcCall(options) {
|
|
|
174
179
|
return result;
|
|
175
180
|
}
|
|
176
181
|
|
|
182
|
+
// Calculate longest base dir by analyzing the list of files
|
|
183
|
+
async function getCodeNarcBaseDirFromFiles(positionalArgs) {
|
|
184
|
+
// All arguments are not files
|
|
185
|
+
if (!positionalArgs.every(fileOrDirOrPattern => fs.existsSync(fileOrDirOrPattern) || directoryExists(fileOrDirOrPattern))) {
|
|
186
|
+
return process.cwd()
|
|
187
|
+
}
|
|
188
|
+
const folders = positionalArgs.map((fileOrDir) => {
|
|
189
|
+
// Dir
|
|
190
|
+
if (directoryExists(fileOrDir)) {
|
|
191
|
+
return path.resolve(fileOrDir);
|
|
192
|
+
}
|
|
193
|
+
// File dir
|
|
194
|
+
const fileAbsolute = path.resolve(fileOrDir);
|
|
195
|
+
return path.dirname(fileAbsolute);
|
|
196
|
+
});
|
|
197
|
+
const baseDirFromFiles = commondir(folders);
|
|
198
|
+
return baseDirFromFiles
|
|
199
|
+
}
|
|
200
|
+
|
|
177
201
|
// Parse XML result file as js object
|
|
178
202
|
async function parseCodeNarcResult(options, codeNarcBaseDir, codeNarcJsonResult, tmpGroovyFileName, parseErrors) {
|
|
179
203
|
if (!codeNarcJsonResult || !codeNarcJsonResult.codeNarc || !codeNarcJsonResult.packages) {
|
package/lib/groovy-lint.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Imports
|
|
2
2
|
const debug = require("debug")("npm-groovy-lint");
|
|
3
|
+
const fs = require("fs-extra");
|
|
3
4
|
const os = require("os");
|
|
4
5
|
const performance = require("perf_hooks").performance;
|
|
5
6
|
|
|
@@ -137,6 +138,17 @@ class NpmGroovyLint {
|
|
|
137
138
|
this.options[configProp] = configProperties[configProp];
|
|
138
139
|
}
|
|
139
140
|
}
|
|
141
|
+
// Try to catch input from stdin. if found, use it as groovy source
|
|
142
|
+
if (this.options._ && this.options._[0] === '-') {
|
|
143
|
+
const stdInData = fs.readFileSync(0, 'utf-8');
|
|
144
|
+
this.options.source = stdInData;
|
|
145
|
+
this.options._ = [];
|
|
146
|
+
this.options.sourcefilepath = this.options.sourcefilepath || process.cwd();
|
|
147
|
+
if (this.options.format || this.options.fix) {
|
|
148
|
+
this.options.output = 'stdout';
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
140
152
|
} catch (err) {
|
|
141
153
|
this.status = 2;
|
|
142
154
|
this.error = {
|
|
@@ -459,12 +471,12 @@ class NpmGroovyLint {
|
|
|
459
471
|
this.options.failon && this.options.failon !== "none"
|
|
460
472
|
? this.options.failon
|
|
461
473
|
: this.options.failonerror
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
474
|
+
? "error"
|
|
475
|
+
: this.options.failonwarning
|
|
476
|
+
? "warning"
|
|
477
|
+
: this.options.failoninfo
|
|
478
|
+
? "info"
|
|
479
|
+
: "none";
|
|
468
480
|
if (failureLevel === "none") {
|
|
469
481
|
return;
|
|
470
482
|
}
|
|
@@ -475,21 +487,27 @@ class NpmGroovyLint {
|
|
|
475
487
|
|
|
476
488
|
// Fail on error
|
|
477
489
|
if (failureLevel === "error" && errorNb > 0) {
|
|
478
|
-
|
|
490
|
+
if (!["json", "sarif", "stdout"].includes(this.outputType)) {
|
|
491
|
+
console.error(`Failure: ${this.lintResult.summary.totalFoundErrorNumber} error(s) have been found`);
|
|
492
|
+
}
|
|
479
493
|
this.status = 1;
|
|
480
494
|
}
|
|
481
495
|
// Fail on warning
|
|
482
496
|
else if (failureLevel === "warning" && (errorNb > 0 || warningNb > 0)) {
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
497
|
+
if (!["json", "sarif", "stdout"].includes(this.outputType)) {
|
|
498
|
+
console.error(
|
|
499
|
+
`Failure: ${this.lintResult.summary.totalFoundErrorNumber} error(s) have been found \n ${this.lintResult.summary.totalFoundWarningNumber} warning(s) have been found`
|
|
500
|
+
);
|
|
501
|
+
}
|
|
486
502
|
this.status = 1;
|
|
487
503
|
}
|
|
488
504
|
// Fail on info
|
|
489
505
|
else if (failureLevel === "info" && (errorNb > 0 || warningNb > 0 || infoNb > 0)) {
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
506
|
+
if (!["json", "sarif", "stdout"].includes(this.outputType)) {
|
|
507
|
+
console.error(
|
|
508
|
+
`Failure: ${this.lintResult.summary.totalFoundErrorNumber} error(s) have been found \n ${this.lintResult.summary.totalFoundWarningNumber} warning(s) have been found \n ${this.lintResult.summary.totalFoundInfoNumber} info(s) have been found`
|
|
509
|
+
);
|
|
510
|
+
}
|
|
493
511
|
this.status = 1;
|
|
494
512
|
}
|
|
495
513
|
}
|
package/lib/output.js
CHANGED
|
@@ -205,7 +205,9 @@ async function processOutput(outputType, output, lintResult, options, fixer = nu
|
|
|
205
205
|
outputString = JSON.stringify(lintResult);
|
|
206
206
|
console.log(outputString);
|
|
207
207
|
}
|
|
208
|
-
}
|
|
208
|
+
}
|
|
209
|
+
// SARIF results
|
|
210
|
+
else if (outputType === "sarif") {
|
|
209
211
|
const sarifJsonString = buildSarifResult(lintResult);
|
|
210
212
|
// SARIF file
|
|
211
213
|
if (output.endsWith(".sarif")) {
|
|
@@ -219,6 +221,10 @@ async function processOutput(outputType, output, lintResult, options, fixer = nu
|
|
|
219
221
|
console.log(sarifJsonString);
|
|
220
222
|
}
|
|
221
223
|
}
|
|
224
|
+
// stdout result for format / fix with source sent as stdin
|
|
225
|
+
else if (outputType === "stdout") {
|
|
226
|
+
console.log(lintResult.files[0].updatedSource);
|
|
227
|
+
}
|
|
222
228
|
return outputString;
|
|
223
229
|
}
|
|
224
230
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "npm-groovy-lint",
|
|
3
|
-
"version": "10.0
|
|
3
|
+
"version": "10.1.0",
|
|
4
4
|
"description": "Lint, format and auto-fix your Groovy / Jenkinsfile / Gradle files",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -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",
|