npm-groovy-lint 9.3.2 → 9.4.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 +6 -0
- package/README.md +1 -1
- package/lib/codenarc-caller.js +1 -1
- package/lib/codenarc-factory.js +19 -13
- package/lib/options.js +2 -2
- package/lib/output.js +73 -0
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## UNRELEASED
|
|
4
4
|
|
|
5
|
+
- Add your updates here :)
|
|
6
|
+
|
|
7
|
+
## [9.4.0] 2022-01-11
|
|
8
|
+
|
|
9
|
+
- Add [SARIF](https://sarifweb.azurewebsites.net/) output format using [node-sarif-builder](https://github.com/nvuillam/node-sarif-builder)
|
|
10
|
+
|
|
5
11
|
## [9.3.2] 2022-01-09
|
|
6
12
|
|
|
7
13
|
- Upgrade cli-progress to avoid [colors lib boring but harmless hack](https://github.com/Marak/colors.js/issues/285)
|
package/README.md
CHANGED
|
@@ -47,7 +47,7 @@ Any **question**, **problem** or **enhancement request** ? Ask [**here**](https:
|
|
|
47
47
|
|-------------------------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
48
48
|
| -p<br/> --path | String | Directory containing the files to lint<br/> Example: `./path/to/my/groovy/files` |
|
|
49
49
|
| -f<br/> --files | String | 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"` |
|
|
50
|
-
| -o<br/> --output | String | Output format (txt,json,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.
|
|
50
|
+
| -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"` |
|
|
51
51
|
| -l<br/> --loglevel | String | Log level (error,warning or info)<br/>Default: info |
|
|
52
52
|
| --failon | String | Defines the error level where CLI will fail (return code = 1). error,warning,info or none. Each failure level includes the more critical ones. |
|
|
53
53
|
| -c<br/> --config | String | Custom path to [GroovyLint config file](#Configuration), or preset config `recommended|recommended-jenkinsfile|all`<br/> Default: Browse current directory to find `.groovylintrc.json|js|yml|package.json` config file, or default npm-groovy-lint config if not defined.<br/>Note: command-line arguments have priority on config file properties |
|
package/lib/codenarc-caller.js
CHANGED
package/lib/codenarc-factory.js
CHANGED
|
@@ -35,7 +35,7 @@ async function prepareCodeNarcCall(options) {
|
|
|
35
35
|
const pathParse = path.parse(options.sourcefilepath);
|
|
36
36
|
cnPath = cnPath + "/codeNarcTmpDir_" + Math.random();
|
|
37
37
|
await fs.ensureDir(cnPath, { mode: "0777" });
|
|
38
|
-
const pathBase = pathParse.base.replace(/ /g,
|
|
38
|
+
const pathBase = pathParse.base.replace(/ /g, "_");
|
|
39
39
|
result.tmpGroovyFileName = path.resolve(cnPath + "/" + pathBase);
|
|
40
40
|
cnFiles = "**/" + pathBase;
|
|
41
41
|
}
|
|
@@ -91,8 +91,14 @@ async function prepareCodeNarcCall(options) {
|
|
|
91
91
|
|
|
92
92
|
// Output
|
|
93
93
|
result.output = options.output.replace(/^"(.*)"$/, "$1");
|
|
94
|
-
if (["txt", "json", "none"].includes(result.output) ||
|
|
95
|
-
result.
|
|
94
|
+
if (["txt", "json", "sarif", "none"].includes(result.output) ||
|
|
95
|
+
result.output.endsWith(".txt") ||
|
|
96
|
+
result.output.endsWith(".sarif") ||
|
|
97
|
+
result.output.endsWith(".json")) {
|
|
98
|
+
result.outputType = result.output.endsWith(".txt") ? "txt"
|
|
99
|
+
: result.output.endsWith(".json") ? "json"
|
|
100
|
+
: result.output.endsWith(".sarif") ? "sarif"
|
|
101
|
+
: result.output;
|
|
96
102
|
result.codenarcArgs.push(`-report=json:stdout`);
|
|
97
103
|
} else if (["html", "xml"].includes(result.output.split(".").pop())) {
|
|
98
104
|
result.outputType = result.output
|
|
@@ -101,11 +107,11 @@ async function prepareCodeNarcCall(options) {
|
|
|
101
107
|
.endsWith("html")
|
|
102
108
|
? "html"
|
|
103
109
|
: result.output
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
110
|
+
.split(".")
|
|
111
|
+
.pop()
|
|
112
|
+
.endsWith("xml")
|
|
113
|
+
? "xml"
|
|
114
|
+
: "";
|
|
109
115
|
const ext = result.output.split(".").pop();
|
|
110
116
|
result.codenarcArgs.push(`-report=${ext}:${result.output}`);
|
|
111
117
|
|
|
@@ -266,7 +272,7 @@ async function parseCodeNarcResult(options, codeNarcBaseDir, codeNarcJsonResult,
|
|
|
266
272
|
}
|
|
267
273
|
|
|
268
274
|
// Parse error definitions & build url if not already done and not noreturnrules option
|
|
269
|
-
if (result.rules == null && options.returnrules === true) {
|
|
275
|
+
if (result.rules == null && (options.returnrules === true || options.output.includes("sarif"))) {
|
|
270
276
|
const configAllFileName = await getConfigFileName(__dirname, null, [".groovylintrc-all.json"]);
|
|
271
277
|
const grooylintrcAllRules = Object.keys(JSON.parse(fs.readFileSync(configAllFileName, "utf8").toString()).rules);
|
|
272
278
|
const rules = {};
|
|
@@ -338,8 +344,8 @@ async function buildRuleSets(options) {
|
|
|
338
344
|
typeof ruleFromConfig === "object"
|
|
339
345
|
? Object.assign(ruleFromConfig, ruleOptions)
|
|
340
346
|
: Object.keys(ruleOptions).length > 0
|
|
341
|
-
|
|
342
|
-
|
|
347
|
+
? ruleOptions
|
|
348
|
+
: ruleFromConfig;
|
|
343
349
|
const ruleDef = buildCodeNarcRule(ruleName, mergedRuleConfig);
|
|
344
350
|
return ruleDef;
|
|
345
351
|
});
|
|
@@ -356,8 +362,8 @@ async function buildRuleSets(options) {
|
|
|
356
362
|
typeof ruleDef === "object"
|
|
357
363
|
? Object.assign(ruleDef, ruleFromRuleSetsArg)
|
|
358
364
|
: Object.keys(ruleFromRuleSetsArg).length > 0
|
|
359
|
-
|
|
360
|
-
|
|
365
|
+
? ruleFromRuleSetsArg
|
|
366
|
+
: ruleDef;
|
|
361
367
|
}
|
|
362
368
|
// Add in the list of rules to test , except if it is disabled
|
|
363
369
|
if (!(ruleDef === "off" || ruleDef.disabled === true || ruleDef.enabled === false)) {
|
package/lib/options.js
CHANGED
|
@@ -119,8 +119,8 @@ module.exports = optionator({
|
|
|
119
119
|
alias: "o",
|
|
120
120
|
type: "String",
|
|
121
121
|
default: "txt",
|
|
122
|
-
description: "Output format (txt,json,html,xml), or path to a file with one of these extensions",
|
|
123
|
-
example: ["txt", "json", "./logs/myLintResults.txt", "./logs/myLintResults.json", "./logs/myLintResults.html", "./logs/myLintResults.xml"]
|
|
122
|
+
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"]
|
|
124
124
|
},
|
|
125
125
|
{
|
|
126
126
|
option: "loglevel",
|
package/lib/output.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Output management
|
|
2
2
|
const c = require("ansi-colors");
|
|
3
3
|
const fse = require("fs-extra");
|
|
4
|
+
const { SarifBuilder, SarifRunBuilder, SarifResultBuilder, SarifRuleBuilder } = require("node-sarif-builder");
|
|
4
5
|
const path = require("path");
|
|
5
6
|
const { isErrorInLogLevelScope } = require("./utils");
|
|
6
7
|
|
|
@@ -204,8 +205,80 @@ async function processOutput(outputType, output, lintResult, options, fixer = nu
|
|
|
204
205
|
outputString = JSON.stringify(lintResult);
|
|
205
206
|
console.log(outputString);
|
|
206
207
|
}
|
|
208
|
+
} else if (outputType === "sarif") {
|
|
209
|
+
const sarifJsonString = buildSarifResult(lintResult);
|
|
210
|
+
// SARIF file
|
|
211
|
+
if (output.endsWith(".sarif")) {
|
|
212
|
+
fse.writeFileSync(output, sarifJsonString);
|
|
213
|
+
const absolutePath = path.resolve(".", output);
|
|
214
|
+
outputString = "GroovyLint: Logged SARIF results in file " + absolutePath;
|
|
215
|
+
console.info(outputString);
|
|
216
|
+
} else {
|
|
217
|
+
// SARIF in stdout
|
|
218
|
+
outputString = sarifJsonString;
|
|
219
|
+
console.log(sarifJsonString);
|
|
220
|
+
}
|
|
207
221
|
}
|
|
208
222
|
return outputString;
|
|
209
223
|
}
|
|
210
224
|
|
|
225
|
+
function buildSarifResult(lintResult) {
|
|
226
|
+
// SARIF builder
|
|
227
|
+
const sarifBuilder = new SarifBuilder();
|
|
228
|
+
// SARIF Run builder
|
|
229
|
+
const sarifRunBuilder = new SarifRunBuilder().initSimple({
|
|
230
|
+
name: "npm-groovy-lint",
|
|
231
|
+
url: "https://nvuillam.github.io/npm-groovy-lint/"
|
|
232
|
+
});
|
|
233
|
+
// SARIF rules
|
|
234
|
+
for (const ruleId of Object.keys(lintResult.rules || {})) {
|
|
235
|
+
const rule = lintResult.rules[ruleId];
|
|
236
|
+
const sarifRuleBuilder = new SarifRuleBuilder().initSimple({
|
|
237
|
+
ruleId: ruleId,
|
|
238
|
+
shortDescriptionText: rule.description,
|
|
239
|
+
helpUri: rule.docUrl
|
|
240
|
+
});
|
|
241
|
+
sarifRunBuilder.addRule(sarifRuleBuilder);
|
|
242
|
+
}
|
|
243
|
+
// Add SARIF results (individual errors)
|
|
244
|
+
for (const fileNm of Object.keys(lintResult.files)) {
|
|
245
|
+
const fileErrors = lintResult.files[fileNm].errors;
|
|
246
|
+
for (const err of fileErrors) {
|
|
247
|
+
const sarifResultBuilder = new SarifResultBuilder();
|
|
248
|
+
const sarifResultInit = {
|
|
249
|
+
level: err.severity === "info" ? "note" : err.severity, // Other values can be "warning" or "error"
|
|
250
|
+
messageText: err.msg,
|
|
251
|
+
ruleId: err.rule,
|
|
252
|
+
fileUri: process.env.SARIF_URI_ABSOLUTE
|
|
253
|
+
? "file:///" + fileNm.replace(/\\/g, "/")
|
|
254
|
+
: path.relative(process.cwd(), fileNm)
|
|
255
|
+
};
|
|
256
|
+
if (err.range) {
|
|
257
|
+
sarifResultInit.startLine = fixLine(err.range.start.line);
|
|
258
|
+
sarifResultInit.startColumn = fixCol(err.range.start.character);
|
|
259
|
+
sarifResultInit.endLine = fixLine(err.range.end.line);
|
|
260
|
+
sarifResultInit.endColumn = fixCol(err.range.end.character);
|
|
261
|
+
}
|
|
262
|
+
sarifResultBuilder.initSimple(sarifResultInit);
|
|
263
|
+
sarifRunBuilder.addResult(sarifResultBuilder);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
sarifBuilder.addRun(sarifRunBuilder);
|
|
267
|
+
return sarifBuilder.buildSarifJsonString({ indent: false });
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function fixLine(val) {
|
|
271
|
+
if (val === null) {
|
|
272
|
+
return undefined;
|
|
273
|
+
}
|
|
274
|
+
return val === 0 ? 1 : val;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function fixCol(val) {
|
|
278
|
+
if (val === null) {
|
|
279
|
+
return undefined;
|
|
280
|
+
}
|
|
281
|
+
return val === 0 ? 1 : val + 1;
|
|
282
|
+
}
|
|
283
|
+
|
|
211
284
|
module.exports = { computeStats, processOutput };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "npm-groovy-lint",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.4.0",
|
|
4
4
|
"description": "Lint, format and auto-fix your Groovy / Jenkinsfile / Gradle files",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"import-fresh": "^3.2.1",
|
|
59
59
|
"ip": "^1.1.5",
|
|
60
60
|
"java-caller": "^2.2.4",
|
|
61
|
+
"node-sarif-builder": "^1.0.0",
|
|
61
62
|
"optionator": "^0.8.3",
|
|
62
63
|
"semver": "^7.1.3",
|
|
63
64
|
"strip-json-comments": "^3.0.1",
|
|
@@ -75,7 +76,7 @@
|
|
|
75
76
|
"eslint-plugin-standard": "^5.0.0",
|
|
76
77
|
"mocha": "^7.0.1",
|
|
77
78
|
"nyc": "^15.1.0",
|
|
78
|
-
"prettier": "1.19.1",
|
|
79
|
+
"prettier": "^1.19.1",
|
|
79
80
|
"rimraf": "^3.0.2",
|
|
80
81
|
"which": "^2.0.2"
|
|
81
82
|
},
|