npm-groovy-lint 11.1.1 → 11.1.2-beta202310271757.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/README.md +16 -15
- package/lib/.groovylintrc-all.json +393 -393
- package/lib/codenarc-caller.js +58 -22
- package/lib/codenarc-factory.js +23 -21
- package/lib/groovy-lint-fix.js +12 -4
- package/lib/groovy-lint.js +13 -13
- package/lib/index.js +0 -0
- package/lib/java/CodeNarcServer.jar +0 -0
- package/lib/java/groovy/lib/commons-cli-1.4.jar +0 -0
- package/lib/java/groovy/lib/groovy-cli-commons-3.0.9.jar +0 -0
- package/lib/java/slf4j-api-2.0.9.jar +0 -0
- package/lib/java/slf4j-simple-2.0.9.jar +0 -0
- package/lib/options.js +15 -5
- package/lib/output.js +3 -3
- package/lib/utils.js +5 -4
- package/package.json +17 -12
- package/CHANGELOG.md +0 -623
- package/lib/java/log4j-api-2.18.0.jar +0 -0
- package/lib/java/log4j-core-2.18.0.jar +0 -0
- package/lib/java/log4j-slf4j-impl-2.18.0.jar +0 -0
- package/lib/java/slf4j-api-1.7.9.jar +0 -0
package/lib/codenarc-caller.js
CHANGED
|
@@ -2,12 +2,17 @@
|
|
|
2
2
|
const axios = require("axios").default;
|
|
3
3
|
const cliProgress = require("cli-progress");
|
|
4
4
|
const debug = require("debug")("npm-groovy-lint");
|
|
5
|
+
const trace = require("debug")("npm-groovy-lint-trace");
|
|
5
6
|
const { JavaCaller } = require("java-caller");
|
|
6
7
|
const optionsDefinition = require("./options");
|
|
7
8
|
const { performance } = require("perf_hooks");
|
|
8
9
|
const { getSourceLines } = require("./utils");
|
|
9
10
|
const c = require("chalk");
|
|
10
11
|
|
|
12
|
+
// Request over IPv4 because Java typically prefers it.
|
|
13
|
+
const http = require("http");
|
|
14
|
+
axios.defaults.httpAgent = new http.Agent({ family: 4, keepAlive: true });
|
|
15
|
+
|
|
11
16
|
class CodeNarcCaller {
|
|
12
17
|
"use strict";
|
|
13
18
|
|
|
@@ -30,16 +35,13 @@ class CodeNarcCaller {
|
|
|
30
35
|
minimumJavaVersion: 8,
|
|
31
36
|
maximumJavaVersion: 14,
|
|
32
37
|
rootPath: __dirname,
|
|
33
|
-
|
|
34
|
-
classPath: "java/CodeNarcServer.jar:java/*"
|
|
38
|
+
jar: "java/CodeNarcServer.jar"
|
|
35
39
|
},
|
|
36
40
|
codeNarcJava: {
|
|
37
41
|
minimumJavaVersion: 8,
|
|
38
42
|
maximumJavaVersion: 14,
|
|
39
43
|
rootPath: __dirname,
|
|
40
|
-
|
|
41
|
-
classPath:
|
|
42
|
-
"java/CodeNarc-3.1.0.jar:java/groovy/lib/groovy-3.0.9.jar:java/groovy/lib/groovy-templates-3.0.9.jar:java/groovy/lib/groovy-xml-3.0.9.jar:java/groovy/lib/groovy-json-3.0.9.jar:java/groovy/lib/groovy-ant-3.0.9.jar:java/groovy/lib/ant-1.10.11.jar:java/groovy/lib/ant-launcher-1.10.11.jar:java/slf4j-api-1.7.9.jar:java/log4j-slf4j-impl-2.18.0.jar:java/log4j-api-2.18.0.jar:java/log4j-core-2.18.0.jar:java/GMetrics-2.1.0.jar:java/*"
|
|
44
|
+
jar: "java/CodeNarcServer.jar"
|
|
43
45
|
}
|
|
44
46
|
};
|
|
45
47
|
|
|
@@ -85,16 +87,17 @@ class CodeNarcCaller {
|
|
|
85
87
|
},
|
|
86
88
|
timeout: 600000
|
|
87
89
|
};
|
|
88
|
-
|
|
90
|
+
trace(`CALL CodeNarcServer with ${JSON.stringify(axiosConfig, null, 2)}`);
|
|
89
91
|
let response;
|
|
90
92
|
try {
|
|
91
93
|
const startCodeNarc = performance.now();
|
|
92
94
|
response = await axios.request(axiosConfig);
|
|
93
95
|
this.serverStatus = "running";
|
|
94
96
|
const elapsed = parseInt(performance.now() - startCodeNarc, 10);
|
|
95
|
-
debug(`CodeNarcServer call result: (${response.status}) ${elapsed}ms
|
|
97
|
+
debug(`CodeNarcServer call result: (${response.status}) ${elapsed}ms`);
|
|
96
98
|
} catch (e) {
|
|
97
99
|
// If server not started , start it and try again
|
|
100
|
+
debug(`callCodeNarcServer code: ${e.code} error: ${e.message}`);
|
|
98
101
|
if (
|
|
99
102
|
(startServerTried === false,
|
|
100
103
|
e.code && ["ECONNREFUSED", "ETIMEDOUT"].includes(e.code) && ["unknown", "running"].includes(this.serverStatus)) // running is here in case the Server auto-killed itself at its expiration time
|
|
@@ -178,7 +181,7 @@ class CodeNarcCaller {
|
|
|
178
181
|
const scriptArgs = this.codenarcArgs;
|
|
179
182
|
|
|
180
183
|
// Start progress bar
|
|
181
|
-
|
|
184
|
+
trace(`CALL CodeNarcJava with ${scriptArgs.join(" ")}`);
|
|
182
185
|
this.bar = new cliProgress.SingleBar(
|
|
183
186
|
{
|
|
184
187
|
format: "[{bar}] Running CodeNarc for {duration_formatted}",
|
|
@@ -208,7 +211,7 @@ class CodeNarcCaller {
|
|
|
208
211
|
if ([666, 1].includes(javaResult.status)) {
|
|
209
212
|
if (!secondAttempt) {
|
|
210
213
|
// If failure (missing class com.nvuillam.CodeNarcServer for example, it can happen on Linux, let's try the original org.codenarc.CodeNarc class)
|
|
211
|
-
|
|
214
|
+
trace(`Error calling CodeNarcServer via java: ${JSON.stringify(javaResult)}`);
|
|
212
215
|
return await this.callCodeNarcJava(true);
|
|
213
216
|
} else {
|
|
214
217
|
let reason = "Reason: unknown";
|
|
@@ -272,12 +275,20 @@ class CodeNarcCaller {
|
|
|
272
275
|
return false;
|
|
273
276
|
}
|
|
274
277
|
|
|
278
|
+
// Store the process so we can stop it later.
|
|
279
|
+
this.codeNarcProcess = javaCallRes.childJavaProcess;
|
|
280
|
+
|
|
275
281
|
// Poll it until it is ready
|
|
276
282
|
const start = performance.now();
|
|
277
283
|
let notified = false;
|
|
278
284
|
let interval;
|
|
279
285
|
await new Promise(resolve => {
|
|
280
286
|
interval = setInterval(() => {
|
|
287
|
+
debug(
|
|
288
|
+
`pinging CodeNarcServer at ${serverPingUri} notified: ${notified}, serverStatus: ${
|
|
289
|
+
this.serverStatus
|
|
290
|
+
}, since: ${performance.now() - start}, maxAttemptTimeMs: ${maxAttemptTimeMs}`
|
|
291
|
+
);
|
|
281
292
|
axios
|
|
282
293
|
.get(serverPingUri)
|
|
283
294
|
.then(response => {
|
|
@@ -291,18 +302,22 @@ class CodeNarcCaller {
|
|
|
291
302
|
resolve();
|
|
292
303
|
}
|
|
293
304
|
} else if (notified === false && this.serverStatus === "unknown" && performance.now() - start > maxAttemptTimeMs) {
|
|
294
|
-
// Timeout has been reached
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
},
|
|
299
|
-
interval
|
|
300
|
-
);
|
|
305
|
+
// Timeout has been reached.
|
|
306
|
+
let since = performance.now() - start;
|
|
307
|
+
debug(`Ping timeout after ${since}ms status: ${response.status}`);
|
|
308
|
+
this.declareServerError({ message: `Timeout after ${since}ms} status: ${response.status}` }, interval);
|
|
301
309
|
resolve();
|
|
302
310
|
}
|
|
303
311
|
})
|
|
304
|
-
.catch(
|
|
305
|
-
|
|
312
|
+
.catch(e => {
|
|
313
|
+
debug(`Ping code: ${e.code} message: ${e.message}`);
|
|
314
|
+
let since = performance.now() - start;
|
|
315
|
+
if (notified === false && this.serverStatus === "unknown" && since > maxAttemptTimeMs) {
|
|
316
|
+
// Timeout has been reached
|
|
317
|
+
debug(`Ping timeout after ${maxAttemptTimeMs}ms`);
|
|
318
|
+
this.declareServerError({ message: `Timeout after ${since}ms error: ${e}` }, interval);
|
|
319
|
+
resolve();
|
|
320
|
+
}
|
|
306
321
|
});
|
|
307
322
|
}, 400);
|
|
308
323
|
});
|
|
@@ -315,8 +330,21 @@ class CodeNarcCaller {
|
|
|
315
330
|
}
|
|
316
331
|
}
|
|
317
332
|
|
|
333
|
+
// Kill CodeNarc process if running.
|
|
334
|
+
killCodeNarcProcess() {
|
|
335
|
+
if (this.codeNarcProcess) {
|
|
336
|
+
this.codeNarcProcess.kill("SIGKILL");
|
|
337
|
+
delete this.codeNarcProcess;
|
|
338
|
+
return "CodeNarcServer killed";
|
|
339
|
+
}
|
|
340
|
+
return "";
|
|
341
|
+
}
|
|
342
|
+
|
|
318
343
|
// Stop polling and log error
|
|
319
344
|
declareServerError(e, interval) {
|
|
345
|
+
// Kill off the process as it is not responding.
|
|
346
|
+
this.killCodeNarcProcess();
|
|
347
|
+
|
|
320
348
|
this.serverStatus = "error";
|
|
321
349
|
if (interval) {
|
|
322
350
|
clearInterval(interval);
|
|
@@ -327,10 +355,16 @@ class CodeNarcCaller {
|
|
|
327
355
|
console.error(c.grey(errMsg));
|
|
328
356
|
}
|
|
329
357
|
|
|
330
|
-
// Kill CodeNarc server
|
|
358
|
+
// Kill CodeNarc server.
|
|
331
359
|
async killCodeNarcServer() {
|
|
360
|
+
// Try by process first as it's more reliable.
|
|
361
|
+
let outputString = this.killCodeNarcProcess();
|
|
362
|
+
if (outputString) {
|
|
363
|
+
return outputString;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Process kill wasn't possible, so try sending a kill http request.
|
|
332
367
|
const serverUri = this.getCodeNarcServerUri() + "/kill";
|
|
333
|
-
let outputString = "";
|
|
334
368
|
try {
|
|
335
369
|
const response = await axios.post(serverUri, { timeout: 5000 });
|
|
336
370
|
if (response.data.status === "killed") {
|
|
@@ -339,10 +373,12 @@ class CodeNarcCaller {
|
|
|
339
373
|
outputString = "Error killing CodeNarcServer";
|
|
340
374
|
}
|
|
341
375
|
} catch (e) {
|
|
342
|
-
if (e.stack.includes("connResetException")) {
|
|
376
|
+
if (e.stack.includes("connResetException") || e.message.includes("socket hang up")) {
|
|
343
377
|
outputString = "CodeNarcServer terminated";
|
|
344
378
|
} else {
|
|
345
|
-
|
|
379
|
+
// This should be ECONNREFUSED.
|
|
380
|
+
debug(`CodeNarcServer kill request failed: ${e}`);
|
|
381
|
+
outputString = `CodeNarcServer was not running`;
|
|
346
382
|
}
|
|
347
383
|
}
|
|
348
384
|
return outputString;
|
package/lib/codenarc-factory.js
CHANGED
|
@@ -56,10 +56,12 @@ async function prepareCodeNarcCall(options) {
|
|
|
56
56
|
|
|
57
57
|
// Define base directory
|
|
58
58
|
const baseBefore = (cnPath !== "." && cnPath.startsWith("/")) || cnPath.includes(":/") || cnPath.includes(":\\") ? "" : process.cwd() + "/";
|
|
59
|
-
const codeNarcBaseDir =
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
const codeNarcBaseDir =
|
|
60
|
+
positionalArgs.length > 0
|
|
61
|
+
? await getCodeNarcBaseDirFromFiles(positionalArgs)
|
|
62
|
+
: cnPath !== "."
|
|
63
|
+
? baseBefore + cnPath.replace(/^"(.*)"$/, "$1")
|
|
64
|
+
: process.cwd();
|
|
63
65
|
result.codeNarcBaseDir = path.resolve(codeNarcBaseDir);
|
|
64
66
|
result.codenarcArgs.push(`-basedir=${result.codeNarcBaseDir}`);
|
|
65
67
|
|
|
@@ -144,10 +146,10 @@ async function prepareCodeNarcCall(options) {
|
|
|
144
146
|
result.outputType = result.output.endsWith(".txt")
|
|
145
147
|
? "txt"
|
|
146
148
|
: result.output.endsWith(".json")
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
149
|
+
? "json"
|
|
150
|
+
: result.output.endsWith(".sarif")
|
|
151
|
+
? "sarif"
|
|
152
|
+
: result.output;
|
|
151
153
|
result.codenarcArgs.push(`-report=json:stdout`);
|
|
152
154
|
} else if (["html", "xml"].includes(result.output.split(".").pop())) {
|
|
153
155
|
result.outputType = result.output
|
|
@@ -156,11 +158,11 @@ async function prepareCodeNarcCall(options) {
|
|
|
156
158
|
.endsWith("html")
|
|
157
159
|
? "html"
|
|
158
160
|
: result.output
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
161
|
+
.split(".")
|
|
162
|
+
.pop()
|
|
163
|
+
.endsWith("xml")
|
|
164
|
+
? "xml"
|
|
165
|
+
: "";
|
|
164
166
|
const ext = result.output.split(".").pop();
|
|
165
167
|
result.codenarcArgs.push(`-report=${ext}:${result.output}`);
|
|
166
168
|
|
|
@@ -183,9 +185,9 @@ async function prepareCodeNarcCall(options) {
|
|
|
183
185
|
async function getCodeNarcBaseDirFromFiles(positionalArgs) {
|
|
184
186
|
// All arguments are not files
|
|
185
187
|
if (!positionalArgs.every(fileOrDirOrPattern => fs.existsSync(fileOrDirOrPattern) || directoryExists(fileOrDirOrPattern))) {
|
|
186
|
-
return process.cwd()
|
|
188
|
+
return process.cwd();
|
|
187
189
|
}
|
|
188
|
-
const folders = positionalArgs.map(
|
|
190
|
+
const folders = positionalArgs.map(fileOrDir => {
|
|
189
191
|
// Dir
|
|
190
192
|
if (directoryExists(fileOrDir)) {
|
|
191
193
|
return path.resolve(fileOrDir);
|
|
@@ -195,7 +197,7 @@ async function getCodeNarcBaseDirFromFiles(positionalArgs) {
|
|
|
195
197
|
return path.dirname(fileAbsolute);
|
|
196
198
|
});
|
|
197
199
|
const baseDirFromFiles = commondir(folders);
|
|
198
|
-
return baseDirFromFiles
|
|
200
|
+
return baseDirFromFiles;
|
|
199
201
|
}
|
|
200
202
|
|
|
201
203
|
// Parse XML result file as js object
|
|
@@ -327,7 +329,7 @@ async function parseCodeNarcResult(options, codeNarcBaseDir, codeNarcJsonResult,
|
|
|
327
329
|
}
|
|
328
330
|
// Add unprecise range based on line when range function has not been defined on rule
|
|
329
331
|
else if (errItem.line > 0) {
|
|
330
|
-
const range = evaluateRangeFromLine(errItem,
|
|
332
|
+
const range = evaluateRangeFromLine(errItem, allLines);
|
|
331
333
|
if (range && range.start.character > -1) {
|
|
332
334
|
errItem.range = range;
|
|
333
335
|
}
|
|
@@ -419,8 +421,8 @@ async function buildRuleSets(options) {
|
|
|
419
421
|
typeof ruleFromConfig === "object"
|
|
420
422
|
? Object.assign(ruleFromConfig, ruleOptions)
|
|
421
423
|
: Object.keys(ruleOptions).length > 0
|
|
422
|
-
|
|
423
|
-
|
|
424
|
+
? ruleOptions
|
|
425
|
+
: ruleFromConfig;
|
|
424
426
|
const ruleDef = buildCodeNarcRule(ruleName, mergedRuleConfig);
|
|
425
427
|
// If rule has been sent as argument, enable it by default
|
|
426
428
|
if (ruleDef.enabled === false) {
|
|
@@ -441,8 +443,8 @@ async function buildRuleSets(options) {
|
|
|
441
443
|
typeof ruleDef === "object"
|
|
442
444
|
? Object.assign(ruleDef, ruleFromRuleSetsArg)
|
|
443
445
|
: Object.keys(ruleFromRuleSetsArg).length > 0
|
|
444
|
-
|
|
445
|
-
|
|
446
|
+
? ruleFromRuleSetsArg
|
|
447
|
+
: ruleDef;
|
|
446
448
|
}
|
|
447
449
|
// Add in the list of rules to test , except if it is disabled
|
|
448
450
|
if (!(ruleDef === "off" || ruleDef.disabled === true || ruleDef.enabled === false)) {
|
package/lib/groovy-lint-fix.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
const fse = require("fs-extra");
|
|
3
3
|
const cliProgress = require("cli-progress");
|
|
4
4
|
const debug = require("debug")("npm-groovy-lint");
|
|
5
|
+
const trace = require("debug")("npm-groovy-lint-trace");
|
|
5
6
|
const os = require("os");
|
|
6
7
|
const { getNpmGroovyLintRules, getFormattingRulesToAlwaysRun } = require("./groovy-lint-rules.js");
|
|
7
8
|
const { evaluateVariables, getSourceLines } = require("./utils.js");
|
|
@@ -48,7 +49,7 @@ class NpmGroovyLintFix {
|
|
|
48
49
|
},
|
|
49
50
|
cliProgress.Presets.shades_classic
|
|
50
51
|
);
|
|
51
|
-
this.bar.start(Object.keys(this.updatedLintResult.files).length, 0);
|
|
52
|
+
this.bar.start(Object.keys(this.updatedLintResult.files).length, 0, { file: "..." });
|
|
52
53
|
|
|
53
54
|
// Parse fixes and process them
|
|
54
55
|
await this.parseFixableErrors(optns.errorIds);
|
|
@@ -135,7 +136,7 @@ class NpmGroovyLintFix {
|
|
|
135
136
|
return a.rule.priority > b.rule.priority ? 1 : a.rule.priority < b.rule.priority ? -1 : 0;
|
|
136
137
|
});
|
|
137
138
|
}
|
|
138
|
-
|
|
139
|
+
trace(`Parsed fixable errors: ${JSON.stringify(this.fixableErrors)}`);
|
|
139
140
|
}
|
|
140
141
|
|
|
141
142
|
// Add fixable error but do not add twice if scope if the full file
|
|
@@ -184,6 +185,9 @@ class NpmGroovyLintFix {
|
|
|
184
185
|
fixSuccess = true;
|
|
185
186
|
this.updateNextErrorsRanges(allLines, allLinesNew, fileFixableError.lineNb, fileNm);
|
|
186
187
|
allLines = allLinesNew;
|
|
188
|
+
debug(`Fixed ${fileFixableError.ruleName} in file ${fileNm}`);
|
|
189
|
+
} else {
|
|
190
|
+
debug(`Skipping ${fileFixableError.ruleName} as no change in file ${fileNm}`);
|
|
187
191
|
}
|
|
188
192
|
}
|
|
189
193
|
// Line scope violation
|
|
@@ -193,6 +197,8 @@ class NpmGroovyLintFix {
|
|
|
193
197
|
if (fixedLine !== line) {
|
|
194
198
|
fixSuccess = true;
|
|
195
199
|
allLines[lineNb] = fixedLine;
|
|
200
|
+
} else {
|
|
201
|
+
debug(`Skipping ${fileFixableError.ruleName} as no change in line: ${line}`);
|
|
196
202
|
}
|
|
197
203
|
}
|
|
198
204
|
// Update lint results
|
|
@@ -256,7 +262,7 @@ class NpmGroovyLintFix {
|
|
|
256
262
|
if (strBefore instanceof RegExp || (!strBefore.includes("{{") && !strAfter.includes("{{"))) {
|
|
257
263
|
newLine = newLine.replace(strBefore, strAfter);
|
|
258
264
|
} else {
|
|
259
|
-
|
|
265
|
+
trace(`GroovyLint: missing replacement variable(s):\n${strBefore}\n${strAfter}\n${JSON.stringify(fixableError)}`);
|
|
260
266
|
}
|
|
261
267
|
}
|
|
262
268
|
// Function defined in rule
|
|
@@ -267,9 +273,11 @@ class NpmGroovyLintFix {
|
|
|
267
273
|
}
|
|
268
274
|
newLine = fix.func(newLine, evaluatedVars, fixableError);
|
|
269
275
|
} catch (e) {
|
|
270
|
-
|
|
276
|
+
trace(`ERROR: Fix function error: ${e.message} / ${JSON.stringify(fixableError)}`);
|
|
271
277
|
throw e;
|
|
272
278
|
}
|
|
279
|
+
} else {
|
|
280
|
+
debug(`Fix type not supported: ${fix.type} / ${JSON.stringify(fixableError)}`);
|
|
273
281
|
}
|
|
274
282
|
return newLine;
|
|
275
283
|
}
|
package/lib/groovy-lint.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Imports
|
|
2
2
|
const debug = require("debug")("npm-groovy-lint");
|
|
3
|
+
const trace = require("debug")("npm-groovy-lint-trace");
|
|
3
4
|
const fs = require("fs-extra");
|
|
4
5
|
const os = require("os");
|
|
5
6
|
const performance = require("perf_hooks").performance;
|
|
@@ -139,16 +140,15 @@ class NpmGroovyLint {
|
|
|
139
140
|
}
|
|
140
141
|
}
|
|
141
142
|
// 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,
|
|
143
|
+
if (this.options._ && this.options._[0] === "-") {
|
|
144
|
+
const stdInData = fs.readFileSync(0, "utf-8");
|
|
144
145
|
this.options.source = stdInData;
|
|
145
146
|
this.options._ = [];
|
|
146
147
|
this.options.sourcefilepath = this.options.sourcefilepath || process.cwd();
|
|
147
148
|
if (this.options.format || this.options.fix) {
|
|
148
|
-
this.options.output =
|
|
149
|
+
this.options.output = "stdout";
|
|
149
150
|
}
|
|
150
151
|
}
|
|
151
|
-
|
|
152
152
|
} catch (err) {
|
|
153
153
|
this.status = 2;
|
|
154
154
|
this.error = {
|
|
@@ -231,7 +231,7 @@ class NpmGroovyLint {
|
|
|
231
231
|
- Call CodeNarcServer via Http (except if --noserver)
|
|
232
232
|
- Launch CodeNarcServer using com.nvuillam.CodeNarcServer, then call CodeNarcServer via Http (except if --noserver)
|
|
233
233
|
- Call CodeNarc java using com.nvuillam.CodeNarcServer (without launching server)
|
|
234
|
-
- Call CodeNarc java using org.codenarc.CodeNarc
|
|
234
|
+
- Call CodeNarc java using org.codenarc.CodeNarc
|
|
235
235
|
*/
|
|
236
236
|
async callCodeNarc() {
|
|
237
237
|
const startPerf = performance.now();
|
|
@@ -358,7 +358,7 @@ class NpmGroovyLint {
|
|
|
358
358
|
}
|
|
359
359
|
lintAgainOptions.fix = false;
|
|
360
360
|
lintAgainOptions.output = "none";
|
|
361
|
-
|
|
361
|
+
trace(`Fix is done, lint again with options ${JSON.stringify(lintAgainOptions)}`);
|
|
362
362
|
const newLinter = new NpmGroovyLint(lintAgainOptions, {
|
|
363
363
|
parseOptions: false,
|
|
364
364
|
origin: "lintAgainAfterFix"
|
|
@@ -469,18 +469,18 @@ class NpmGroovyLint {
|
|
|
469
469
|
manageReturnCode() {
|
|
470
470
|
if (this.status > 1) {
|
|
471
471
|
// There has been a fatal error before, so there are no results
|
|
472
|
-
return
|
|
472
|
+
return;
|
|
473
473
|
}
|
|
474
474
|
const failureLevel =
|
|
475
475
|
this.options.failon && this.options.failon !== "none"
|
|
476
476
|
? this.options.failon
|
|
477
477
|
: this.options.failonerror
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
478
|
+
? "error"
|
|
479
|
+
: this.options.failonwarning
|
|
480
|
+
? "warning"
|
|
481
|
+
: this.options.failoninfo
|
|
482
|
+
? "info"
|
|
483
|
+
: "none";
|
|
484
484
|
if (failureLevel === "none") {
|
|
485
485
|
return;
|
|
486
486
|
}
|
package/lib/index.js
CHANGED
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/lib/options.js
CHANGED
|
@@ -11,12 +11,13 @@
|
|
|
11
11
|
|
|
12
12
|
const optionator = require("optionator");
|
|
13
13
|
|
|
14
|
+
const defaultServerPort = process.env.SERVER_PORT ? process.env.SERVER_PORT : "7484";
|
|
15
|
+
|
|
14
16
|
//------------------------------------------------------------------------------
|
|
15
17
|
// Initialization and Public Interface
|
|
16
18
|
//------------------------------------------------------------------------------
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
module.exports = optionator({
|
|
20
|
+
let options = optionator({
|
|
20
21
|
prepend: "npm-groovy-lint [options]",
|
|
21
22
|
defaults: {
|
|
22
23
|
concatRepeatedArrays: true,
|
|
@@ -177,14 +178,14 @@ module.exports = optionator({
|
|
|
177
178
|
{
|
|
178
179
|
option: "serverhost",
|
|
179
180
|
type: "String",
|
|
180
|
-
default: "http://localhost",
|
|
181
|
+
default: "http://localhost",
|
|
181
182
|
description: "If use of CodeNarc server, host where is the CodeNarc server (default: localhost)"
|
|
182
183
|
},
|
|
183
184
|
{
|
|
184
185
|
option: "serverport",
|
|
185
186
|
type: "String",
|
|
186
|
-
default:
|
|
187
|
-
description:
|
|
187
|
+
default: defaultServerPort,
|
|
188
|
+
description: `If use of CodeNarc server, port of the CodeNarc server (default: ${defaultServerPort})`,
|
|
188
189
|
example: ["2702"]
|
|
189
190
|
},
|
|
190
191
|
{
|
|
@@ -284,3 +285,12 @@ module.exports = optionator({
|
|
|
284
285
|
]
|
|
285
286
|
]
|
|
286
287
|
});
|
|
288
|
+
|
|
289
|
+
options.defaultServerPort = defaultServerPort;
|
|
290
|
+
|
|
291
|
+
// Export:
|
|
292
|
+
// - parse(args)
|
|
293
|
+
// - generateHelp()
|
|
294
|
+
// - generateHelpForOption(optionName)
|
|
295
|
+
// - defaultServerPort
|
|
296
|
+
module.exports = options;
|
package/lib/output.js
CHANGED
|
@@ -109,12 +109,12 @@ async function processOutput(outputType, output, lintResult, options, fixer = nu
|
|
|
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
|
+
let showFileInOutput = false;
|
|
113
113
|
for (const err of fileErrors) {
|
|
114
114
|
if (!isErrorInLogLevelScope(err.severity, options.loglevel)) {
|
|
115
115
|
continue;
|
|
116
116
|
}
|
|
117
|
-
showFileInOutput = true
|
|
117
|
+
showFileInOutput = true;
|
|
118
118
|
let color = "grey";
|
|
119
119
|
switch (err.severity) {
|
|
120
120
|
case "error":
|
|
@@ -150,7 +150,7 @@ async function processOutput(outputType, output, lintResult, options, fixer = nu
|
|
|
150
150
|
}
|
|
151
151
|
fileOutputString += "\n";
|
|
152
152
|
if (showFileInOutput || options.verbose) {
|
|
153
|
-
outputString += fileOutputString
|
|
153
|
+
outputString += fileOutputString;
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
156
|
outputString += "\nnpm-groovy-lint results in " + c.bold(lintResult.summary.totalFilesLinted) + " linted files:";
|
package/lib/utils.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
const debug = require("debug")("npm-groovy-lint");
|
|
5
|
+
const trace = require("debug")("npm-groovy-lint-trace");
|
|
5
6
|
const decodeHtml = require("decode-html");
|
|
6
7
|
const fse = require("fs-extra");
|
|
7
8
|
const os = require("os");
|
|
@@ -124,7 +125,7 @@ function evaluateRange(errItem, rule, evaluatedVars, errLine, allLines) {
|
|
|
124
125
|
|
|
125
126
|
// Get position to highlight in sources
|
|
126
127
|
function evaluateRangeFromLine(errItem, allLines) {
|
|
127
|
-
return getDefaultRange(allLines, errItem)
|
|
128
|
+
return getDefaultRange(allLines, errItem);
|
|
128
129
|
}
|
|
129
130
|
|
|
130
131
|
// Evaluate variables from messages
|
|
@@ -142,14 +143,14 @@ function evaluateVariables(variableDefs, msg) {
|
|
|
142
143
|
varDef.type && varDef.type === "number"
|
|
143
144
|
? parseInt(value, 10)
|
|
144
145
|
: varDef.type && varDef.type === "array"
|
|
145
|
-
|
|
146
|
-
|
|
146
|
+
? JSON.parse(value)
|
|
147
|
+
: value;
|
|
147
148
|
evaluatedVars.push({
|
|
148
149
|
name: varDef.name,
|
|
149
150
|
value: varValue
|
|
150
151
|
});
|
|
151
152
|
} else {
|
|
152
|
-
|
|
153
|
+
trace(`GroovyLint: Unable to match ${varDef.regex} in ${msg}`);
|
|
153
154
|
}
|
|
154
155
|
}
|
|
155
156
|
}
|
package/package.json
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "npm-groovy-lint",
|
|
3
|
-
"version": "11.1.
|
|
3
|
+
"version": "11.1.2-beta202310271757.0",
|
|
4
4
|
"description": "Lint, format and auto-fix your Groovy / Jenkinsfile / Gradle files",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"lint:fix": "eslint **/*.js --fix && prettier --write \"./lib/**/*.{js,jsx}\" --tab-width 4 --print-width 150",
|
|
8
|
-
"
|
|
9
|
-
"
|
|
8
|
+
"server:run-from-source": "npm run dev:kill-server && groovy -cp \"lib/java/*\" groovy/src/main/com/nvuillam/CodeNarcServer.groovy --server",
|
|
9
|
+
"server:run": "npm run dev:kill-server && java -Xms256m -Xmx2048m -jar lib/java/CodeNarcServer.jar --server",
|
|
10
|
+
"server:build": "node scripts/build-server.js",
|
|
10
11
|
"test": "npm run dev:kill-server && mocha \"test/**/*.test.js\"",
|
|
11
12
|
"test:coverage": "nyc npm run test",
|
|
12
13
|
"test:debug": "npm run dev:kill-server && mocha --reporter spec --inspect-brk \"test/**/*.test.js\"",
|
|
13
|
-
"build": "node
|
|
14
|
+
"build": "node scripts/build-config-all.js && cp -f README.md docs/index.md && cp -f CHANGELOG.md docs/CHANGELOG.md",
|
|
14
15
|
"dev:kill-server": "npm-groovy-lint --killserver",
|
|
15
16
|
"dev:lint-install-local": "npm run dev:kill-server && npm run lint:fix && npm link --force",
|
|
16
|
-
"dev:lint-install-local-copy-vscode": "npm run dev:lint-install-local && node
|
|
17
|
+
"dev:lint-install-local-copy-vscode": "npm run dev:lint-install-local && node scripts/deploy-in-vscode.js",
|
|
18
|
+
"dev:pre-commit": "npm-run-all lint:fix build server:build"
|
|
17
19
|
},
|
|
18
20
|
"repository": {
|
|
19
21
|
"type": "git",
|
|
@@ -48,7 +50,7 @@
|
|
|
48
50
|
"ansi-colors": "^4.1.1",
|
|
49
51
|
"axios": "^0.21.1",
|
|
50
52
|
"chalk": "^4.1.2",
|
|
51
|
-
"cli-progress": "^3.
|
|
53
|
+
"cli-progress": "^3.12.0",
|
|
52
54
|
"commondir": "^1.0.1",
|
|
53
55
|
"debug": "^4.1.1",
|
|
54
56
|
"decode-html": "^2.0.0",
|
|
@@ -60,25 +62,28 @@
|
|
|
60
62
|
"ip": "^1.1.5",
|
|
61
63
|
"java-caller": "^2.2.4",
|
|
62
64
|
"js-yaml": "^4.1.0",
|
|
63
|
-
"node-sarif-builder": "^2.0.
|
|
65
|
+
"node-sarif-builder": "^2.0.3",
|
|
64
66
|
"optionator": "^0.8.3",
|
|
65
67
|
"semver": "^7.1.3",
|
|
66
68
|
"strip-json-comments": "^3.0.1",
|
|
67
69
|
"uuid": "^8.2.0"
|
|
68
70
|
},
|
|
69
71
|
"devDependencies": {
|
|
70
|
-
"@babel/core": "^7.
|
|
71
|
-
"@babel/eslint-parser": "^7.
|
|
72
|
+
"@babel/core": "^7.23.2",
|
|
73
|
+
"@babel/eslint-parser": "^7.22.15",
|
|
74
|
+
"adm-zip": "^0.5.10",
|
|
72
75
|
"diff": "^4.0.2",
|
|
73
|
-
"eslint": "^8.
|
|
74
|
-
"
|
|
76
|
+
"eslint": "^8.52.0",
|
|
77
|
+
"handlebars": "^4.7.8",
|
|
78
|
+
"mocha": "^10.2.0",
|
|
79
|
+
"npm-run-all": "^4.1.5",
|
|
75
80
|
"nyc": "^15.1.0",
|
|
76
81
|
"prettier": "^1.19.1",
|
|
77
82
|
"rimraf": "^3.0.2",
|
|
78
83
|
"which": "^2.0.2"
|
|
79
84
|
},
|
|
80
85
|
"engines": {
|
|
81
|
-
"node": ">=
|
|
86
|
+
"node": ">=18.0.0"
|
|
82
87
|
},
|
|
83
88
|
"mocha": {
|
|
84
89
|
"require": [
|