@herb-tools/linter 0.4.3 → 0.5.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 +216 -19
- package/dist/herb-lint.js +420 -205
- package/dist/herb-lint.js.map +1 -1
- package/dist/index.cjs +61 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +61 -43
- package/dist/index.js.map +1 -1
- package/dist/package.json +4 -4
- package/dist/src/cli/argument-parser.js +28 -18
- package/dist/src/cli/argument-parser.js.map +1 -1
- package/dist/src/cli/file-processor.js +19 -13
- package/dist/src/cli/file-processor.js.map +1 -1
- package/dist/src/cli/formatters/detailed-formatter.js +9 -9
- package/dist/src/cli/formatters/detailed-formatter.js.map +1 -1
- package/dist/src/cli/formatters/github-actions-formatter.js +50 -0
- package/dist/src/cli/formatters/github-actions-formatter.js.map +1 -0
- package/dist/src/cli/formatters/index.js +2 -0
- package/dist/src/cli/formatters/index.js.map +1 -1
- package/dist/src/cli/formatters/json-formatter.js +58 -0
- package/dist/src/cli/formatters/json-formatter.js.map +1 -0
- package/dist/src/cli/formatters/simple-formatter.js +15 -15
- package/dist/src/cli/formatters/simple-formatter.js.map +1 -1
- package/dist/src/cli/output-manager.js +120 -0
- package/dist/src/cli/output-manager.js.map +1 -0
- package/dist/src/cli/summary-reporter.js +22 -22
- package/dist/src/cli/summary-reporter.js.map +1 -1
- package/dist/src/cli.js +41 -26
- package/dist/src/cli.js.map +1 -1
- package/dist/src/default-rules.js +2 -0
- package/dist/src/default-rules.js.map +1 -1
- package/dist/src/linter.js +1 -1
- package/dist/src/linter.js.map +1 -1
- package/dist/src/rules/erb-no-empty-tags.js +2 -2
- package/dist/src/rules/erb-no-empty-tags.js.map +1 -1
- package/dist/src/rules/erb-no-output-control-flow.js +2 -2
- package/dist/src/rules/erb-no-output-control-flow.js.map +1 -1
- package/dist/src/rules/erb-prefer-image-tag-helper.js +2 -2
- package/dist/src/rules/erb-prefer-image-tag-helper.js.map +1 -1
- package/dist/src/rules/erb-require-whitespace-inside-tags.js +2 -2
- package/dist/src/rules/erb-require-whitespace-inside-tags.js.map +1 -1
- package/dist/src/rules/erb-requires-trailing-newline.js.map +1 -1
- package/dist/src/rules/html-anchor-require-href.js +2 -2
- package/dist/src/rules/html-anchor-require-href.js.map +1 -1
- package/dist/src/rules/html-aria-attribute-must-be-valid.js +2 -2
- package/dist/src/rules/html-aria-attribute-must-be-valid.js.map +1 -1
- package/dist/src/rules/html-aria-level-must-be-valid.js +2 -2
- package/dist/src/rules/html-aria-level-must-be-valid.js.map +1 -1
- package/dist/src/rules/html-aria-role-heading-requires-level.js +2 -2
- package/dist/src/rules/html-aria-role-heading-requires-level.js.map +1 -1
- package/dist/src/rules/html-aria-role-must-be-valid.js +2 -2
- package/dist/src/rules/html-aria-role-must-be-valid.js.map +1 -1
- package/dist/src/rules/html-attribute-double-quotes.js +2 -2
- package/dist/src/rules/html-attribute-double-quotes.js.map +1 -1
- package/dist/src/rules/html-attribute-values-require-quotes.js +2 -2
- package/dist/src/rules/html-attribute-values-require-quotes.js.map +1 -1
- package/dist/src/rules/html-boolean-attributes-no-value.js +2 -2
- package/dist/src/rules/html-boolean-attributes-no-value.js.map +1 -1
- package/dist/src/rules/html-img-require-alt.js +2 -2
- package/dist/src/rules/html-img-require-alt.js.map +1 -1
- package/dist/src/rules/html-no-block-inside-inline.js +4 -4
- package/dist/src/rules/html-no-block-inside-inline.js.map +1 -1
- package/dist/src/rules/html-no-duplicate-attributes.js +2 -2
- package/dist/src/rules/html-no-duplicate-attributes.js.map +1 -1
- package/dist/src/rules/html-no-duplicate-ids.js +2 -2
- package/dist/src/rules/html-no-duplicate-ids.js.map +1 -1
- package/dist/src/rules/html-no-empty-headings.js +2 -2
- package/dist/src/rules/html-no-empty-headings.js.map +1 -1
- package/dist/src/rules/html-no-nested-links.js +2 -2
- package/dist/src/rules/html-no-nested-links.js.map +1 -1
- package/dist/src/rules/html-tag-name-lowercase.js +2 -2
- package/dist/src/rules/html-tag-name-lowercase.js.map +1 -1
- package/dist/src/rules/parser-no-errors.js +18 -0
- package/dist/src/rules/parser-no-errors.js.map +1 -0
- package/dist/src/rules/svg-tag-name-capitalization.js +2 -2
- package/dist/src/rules/svg-tag-name-capitalization.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/cli/argument-parser.d.ts +2 -1
- package/dist/types/cli/file-processor.d.ts +6 -5
- package/dist/types/cli/formatters/base-formatter.d.ts +2 -2
- package/dist/types/cli/formatters/detailed-formatter.d.ts +2 -2
- package/dist/types/cli/formatters/github-actions-formatter.d.ts +12 -0
- package/dist/types/cli/formatters/index.d.ts +2 -0
- package/dist/types/cli/formatters/json-formatter.d.ts +42 -0
- package/dist/types/cli/formatters/simple-formatter.d.ts +2 -2
- package/dist/types/cli/output-manager.d.ts +31 -0
- package/dist/types/cli/summary-reporter.d.ts +3 -3
- package/dist/types/cli.d.ts +3 -1
- package/dist/types/rules/erb-no-empty-tags.d.ts +2 -2
- package/dist/types/rules/erb-no-output-control-flow.d.ts +2 -2
- package/dist/types/rules/erb-prefer-image-tag-helper.d.ts +2 -2
- package/dist/types/rules/erb-require-whitespace-inside-tags.d.ts +2 -2
- package/dist/types/rules/html-anchor-require-href.d.ts +2 -2
- package/dist/types/rules/html-aria-attribute-must-be-valid.d.ts +2 -2
- package/dist/types/rules/html-aria-level-must-be-valid.d.ts +2 -2
- package/dist/types/rules/html-aria-role-heading-requires-level.d.ts +2 -2
- package/dist/types/rules/html-aria-role-must-be-valid.d.ts +2 -2
- package/dist/types/rules/html-attribute-double-quotes.d.ts +2 -2
- package/dist/types/rules/html-attribute-values-require-quotes.d.ts +2 -2
- package/dist/types/rules/html-boolean-attributes-no-value.d.ts +2 -2
- package/dist/types/rules/html-img-require-alt.d.ts +2 -2
- package/dist/types/rules/html-no-block-inside-inline.d.ts +2 -2
- package/dist/types/rules/html-no-duplicate-attributes.d.ts +2 -2
- package/dist/types/rules/html-no-duplicate-ids.d.ts +2 -2
- package/dist/types/rules/html-no-empty-headings.d.ts +2 -2
- package/dist/types/rules/html-no-nested-links.d.ts +2 -2
- package/dist/types/rules/html-tag-name-lowercase.d.ts +2 -2
- package/dist/types/rules/parser-no-errors.d.ts +8 -0
- package/dist/types/rules/svg-tag-name-capitalization.d.ts +2 -2
- package/dist/types/src/cli/argument-parser.d.ts +2 -1
- package/dist/types/src/cli/file-processor.d.ts +6 -5
- package/dist/types/src/cli/formatters/base-formatter.d.ts +2 -2
- package/dist/types/src/cli/formatters/detailed-formatter.d.ts +2 -2
- package/dist/types/src/cli/formatters/github-actions-formatter.d.ts +12 -0
- package/dist/types/src/cli/formatters/index.d.ts +2 -0
- package/dist/types/src/cli/formatters/json-formatter.d.ts +42 -0
- package/dist/types/src/cli/formatters/simple-formatter.d.ts +2 -2
- package/dist/types/src/cli/output-manager.d.ts +31 -0
- package/dist/types/src/cli/summary-reporter.d.ts +3 -3
- package/dist/types/src/cli.d.ts +3 -1
- package/dist/types/src/rules/erb-no-empty-tags.d.ts +2 -2
- package/dist/types/src/rules/erb-no-output-control-flow.d.ts +2 -2
- package/dist/types/src/rules/erb-prefer-image-tag-helper.d.ts +2 -2
- package/dist/types/src/rules/erb-require-whitespace-inside-tags.d.ts +2 -2
- package/dist/types/src/rules/html-anchor-require-href.d.ts +2 -2
- package/dist/types/src/rules/html-aria-attribute-must-be-valid.d.ts +2 -2
- package/dist/types/src/rules/html-aria-level-must-be-valid.d.ts +2 -2
- package/dist/types/src/rules/html-aria-role-heading-requires-level.d.ts +2 -2
- package/dist/types/src/rules/html-aria-role-must-be-valid.d.ts +2 -2
- package/dist/types/src/rules/html-attribute-double-quotes.d.ts +2 -2
- package/dist/types/src/rules/html-attribute-values-require-quotes.d.ts +2 -2
- package/dist/types/src/rules/html-boolean-attributes-no-value.d.ts +2 -2
- package/dist/types/src/rules/html-img-require-alt.d.ts +2 -2
- package/dist/types/src/rules/html-no-block-inside-inline.d.ts +2 -2
- package/dist/types/src/rules/html-no-duplicate-attributes.d.ts +2 -2
- package/dist/types/src/rules/html-no-duplicate-ids.d.ts +2 -2
- package/dist/types/src/rules/html-no-empty-headings.d.ts +2 -2
- package/dist/types/src/rules/html-no-nested-links.d.ts +2 -2
- package/dist/types/src/rules/html-tag-name-lowercase.d.ts +2 -2
- package/dist/types/src/rules/parser-no-errors.d.ts +8 -0
- package/dist/types/src/rules/svg-tag-name-capitalization.d.ts +2 -2
- package/dist/types/src/types.d.ts +3 -3
- package/dist/types/types.d.ts +3 -3
- package/docs/rules/README.md +1 -0
- package/docs/rules/parser-no-errors.md +84 -0
- package/package.json +4 -4
- package/src/cli/argument-parser.ts +33 -19
- package/src/cli/file-processor.ts +25 -17
- package/src/cli/formatters/base-formatter.ts +2 -2
- package/src/cli/formatters/detailed-formatter.ts +9 -9
- package/src/cli/formatters/github-actions-formatter.ts +70 -0
- package/src/cli/formatters/index.ts +2 -0
- package/src/cli/formatters/json-formatter.ts +107 -0
- package/src/cli/formatters/simple-formatter.ts +15 -15
- package/src/cli/output-manager.ts +143 -0
- package/src/cli/summary-reporter.ts +24 -24
- package/src/cli.ts +48 -31
- package/src/default-rules.ts +2 -0
- package/src/linter.ts +1 -1
- package/src/rules/erb-no-empty-tags.ts +3 -3
- package/src/rules/erb-no-output-control-flow.ts +3 -3
- package/src/rules/erb-prefer-image-tag-helper.ts +3 -3
- package/src/rules/erb-require-whitespace-inside-tags.ts +3 -3
- package/src/rules/erb-requires-trailing-newline.ts +2 -0
- package/src/rules/html-anchor-require-href.ts +3 -3
- package/src/rules/html-aria-attribute-must-be-valid.ts +3 -3
- package/src/rules/html-aria-level-must-be-valid.ts +3 -3
- package/src/rules/html-aria-role-heading-requires-level.ts +3 -3
- package/src/rules/html-aria-role-must-be-valid.ts +3 -3
- package/src/rules/html-attribute-double-quotes.ts +3 -3
- package/src/rules/html-attribute-values-require-quotes.ts +3 -3
- package/src/rules/html-boolean-attributes-no-value.ts +3 -3
- package/src/rules/html-img-require-alt.ts +3 -3
- package/src/rules/html-no-block-inside-inline.ts +5 -5
- package/src/rules/html-no-duplicate-attributes.ts +3 -3
- package/src/rules/html-no-duplicate-ids.ts +3 -3
- package/src/rules/html-no-empty-headings.ts +3 -3
- package/src/rules/html-no-nested-links.ts +3 -3
- package/src/rules/html-tag-name-lowercase.ts +3 -3
- package/src/rules/parser-no-errors.ts +25 -0
- package/src/rules/svg-tag-name-capitalization.ts +3 -3
- package/src/types.ts +3 -3
|
@@ -5,24 +5,30 @@ import { Linter } from "../linter.js";
|
|
|
5
5
|
import { colorize } from "@herb-tools/highlighter";
|
|
6
6
|
export class FileProcessor {
|
|
7
7
|
linter = null;
|
|
8
|
-
async processFiles(files) {
|
|
8
|
+
async processFiles(files, formatOption = 'detailed') {
|
|
9
9
|
let totalErrors = 0;
|
|
10
10
|
let totalWarnings = 0;
|
|
11
|
-
let
|
|
11
|
+
let filesWithOffenses = 0;
|
|
12
12
|
let ruleCount = 0;
|
|
13
|
-
const
|
|
14
|
-
const
|
|
13
|
+
const allOffenses = [];
|
|
14
|
+
const ruleOffenses = new Map();
|
|
15
15
|
for (const filename of files) {
|
|
16
16
|
const filePath = resolve(filename);
|
|
17
17
|
const content = readFileSync(filePath, "utf-8");
|
|
18
18
|
const parseResult = Herb.parse(content);
|
|
19
19
|
if (parseResult.errors.length > 0) {
|
|
20
|
-
|
|
20
|
+
if (formatOption !== 'json' && formatOption !== 'github') {
|
|
21
|
+
console.error(`${colorize(filename, "cyan")} - ${colorize("Parse errors:", "brightRed")}`);
|
|
22
|
+
for (const error of parseResult.errors) {
|
|
23
|
+
console.error(` ${colorize("✗", "brightRed")} ${error.message}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// Add parse errors to offenses for JSON output
|
|
21
27
|
for (const error of parseResult.errors) {
|
|
22
|
-
|
|
28
|
+
allOffenses.push({ filename, offense: error, content });
|
|
23
29
|
}
|
|
24
30
|
totalErrors++;
|
|
25
|
-
|
|
31
|
+
filesWithOffenses++;
|
|
26
32
|
continue;
|
|
27
33
|
}
|
|
28
34
|
if (!this.linter) {
|
|
@@ -33,24 +39,24 @@ export class FileProcessor {
|
|
|
33
39
|
ruleCount = this.linter.getRuleCount();
|
|
34
40
|
}
|
|
35
41
|
if (lintResult.offenses.length === 0) {
|
|
36
|
-
if (files.length === 1) {
|
|
42
|
+
if (files.length === 1 && formatOption !== 'json' && formatOption !== 'github') {
|
|
37
43
|
console.log(`${colorize("✓", "brightGreen")} ${colorize(filename, "cyan")} - ${colorize("No issues found", "green")}`);
|
|
38
44
|
}
|
|
39
45
|
}
|
|
40
46
|
else {
|
|
41
47
|
for (const offense of lintResult.offenses) {
|
|
42
|
-
|
|
43
|
-
const ruleData =
|
|
48
|
+
allOffenses.push({ filename, offense: offense, content });
|
|
49
|
+
const ruleData = ruleOffenses.get(offense.rule) || { count: 0, files: new Set() };
|
|
44
50
|
ruleData.count++;
|
|
45
51
|
ruleData.files.add(filename);
|
|
46
|
-
|
|
52
|
+
ruleOffenses.set(offense.rule, ruleData);
|
|
47
53
|
}
|
|
48
54
|
totalErrors += lintResult.errors;
|
|
49
55
|
totalWarnings += lintResult.warnings;
|
|
50
|
-
|
|
56
|
+
filesWithOffenses++;
|
|
51
57
|
}
|
|
52
58
|
}
|
|
53
|
-
return { totalErrors, totalWarnings,
|
|
59
|
+
return { totalErrors, totalWarnings, filesWithOffenses, ruleCount, allOffenses, ruleOffenses };
|
|
54
60
|
}
|
|
55
61
|
}
|
|
56
62
|
//# sourceMappingURL=file-processor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-processor.js","sourceRoot":"","sources":["../../../src/cli/file-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAA;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAC9B,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAA;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"file-processor.js","sourceRoot":"","sources":["../../../src/cli/file-processor.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,8 +11,8 @@ export class DetailedFormatter extends BaseFormatter {
|
|
|
11
11
|
this.wrapLines = wrapLines;
|
|
12
12
|
this.truncateLines = truncateLines;
|
|
13
13
|
}
|
|
14
|
-
async format(
|
|
15
|
-
if (
|
|
14
|
+
async format(allOffenses, isSingleFile = false) {
|
|
15
|
+
if (allOffenses.length === 0)
|
|
16
16
|
return;
|
|
17
17
|
if (!this.highlighter) {
|
|
18
18
|
this.highlighter = new Highlighter(this.theme);
|
|
@@ -20,8 +20,8 @@ export class DetailedFormatter extends BaseFormatter {
|
|
|
20
20
|
}
|
|
21
21
|
if (isSingleFile) {
|
|
22
22
|
// For single file, use inline diagnostics with syntax highlighting
|
|
23
|
-
const { filename, content } =
|
|
24
|
-
const diagnostics =
|
|
23
|
+
const { filename, content } = allOffenses[0];
|
|
24
|
+
const diagnostics = allOffenses.map(item => item.offense);
|
|
25
25
|
const highlighted = this.highlighter.highlight(filename, content, {
|
|
26
26
|
diagnostics: diagnostics,
|
|
27
27
|
splitDiagnostics: true, // Use split mode to show each diagnostic separately
|
|
@@ -33,10 +33,10 @@ export class DetailedFormatter extends BaseFormatter {
|
|
|
33
33
|
}
|
|
34
34
|
else {
|
|
35
35
|
// For multiple files, show individual diagnostics with syntax highlighting
|
|
36
|
-
const totalMessageCount =
|
|
37
|
-
for (let i = 0; i <
|
|
38
|
-
const { filename,
|
|
39
|
-
const formatted = this.highlighter.highlightDiagnostic(filename,
|
|
36
|
+
const totalMessageCount = allOffenses.length;
|
|
37
|
+
for (let i = 0; i < allOffenses.length; i++) {
|
|
38
|
+
const { filename, offense, content } = allOffenses[i];
|
|
39
|
+
const formatted = this.highlighter.highlightDiagnostic(filename, offense, content, {
|
|
40
40
|
contextLines: 2,
|
|
41
41
|
wrapLines: this.wrapLines,
|
|
42
42
|
truncateLines: this.truncateLines
|
|
@@ -54,7 +54,7 @@ export class DetailedFormatter extends BaseFormatter {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
formatFile(_filename,
|
|
57
|
+
formatFile(_filename, _offenses) {
|
|
58
58
|
// Not used in detailed formatter
|
|
59
59
|
throw new Error("formatFile is not implemented for DetailedFormatter");
|
|
60
60
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detailed-formatter.js","sourceRoot":"","sources":["../../../../src/cli/formatters/detailed-formatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAmB,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAE/F,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAKnD,MAAM,OAAO,iBAAkB,SAAQ,aAAa;IAC1C,WAAW,GAAuB,IAAI,CAAA;IACtC,KAAK,CAAY;IACjB,SAAS,CAAS;IAClB,aAAa,CAAS;IAE9B,YAAY,QAAoB,aAAa,EAAE,YAAqB,IAAI,EAAE,gBAAyB,KAAK;QACtG,KAAK,EAAE,CAAA;QACP,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,aAAa,GAAG,aAAa,CAAA;IACpC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"detailed-formatter.js","sourceRoot":"","sources":["../../../../src/cli/formatters/detailed-formatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { BaseFormatter } from "./base-formatter.js";
|
|
2
|
+
// https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-commands
|
|
3
|
+
export class GitHubActionsFormatter extends BaseFormatter {
|
|
4
|
+
static MESSAGE_ESCAPE_MAP = {
|
|
5
|
+
'%': '%25',
|
|
6
|
+
'\n': '%0A',
|
|
7
|
+
'\r': '%0D'
|
|
8
|
+
};
|
|
9
|
+
static PARAM_ESCAPE_MAP = {
|
|
10
|
+
'%': '%25',
|
|
11
|
+
'\n': '%0A',
|
|
12
|
+
'\r': '%0D',
|
|
13
|
+
':': '%3A',
|
|
14
|
+
',': '%2C'
|
|
15
|
+
};
|
|
16
|
+
async format(allDiagnostics) {
|
|
17
|
+
for (const { filename, offense } of allDiagnostics) {
|
|
18
|
+
this.formatDiagnostic(filename, offense);
|
|
19
|
+
}
|
|
20
|
+
if (allDiagnostics.length > 0) {
|
|
21
|
+
console.log();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
formatFile(filename, diagnostics) {
|
|
25
|
+
for (const diagnostic of diagnostics) {
|
|
26
|
+
this.formatDiagnostic(filename, diagnostic);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// GitHub Actions annotation format:
|
|
30
|
+
// ::{level} file={file},line={line},col={col}::{message}
|
|
31
|
+
//
|
|
32
|
+
formatDiagnostic(filename, diagnostic) {
|
|
33
|
+
const level = diagnostic.severity === "error" ? "error" : "warning";
|
|
34
|
+
const { line, column } = diagnostic.location.start;
|
|
35
|
+
const escapedFilename = this.escapeParam(filename);
|
|
36
|
+
const message = this.escapeMessage(diagnostic.message);
|
|
37
|
+
let fullMessage = message;
|
|
38
|
+
if (diagnostic.code) {
|
|
39
|
+
fullMessage += ` [${diagnostic.code}]`;
|
|
40
|
+
}
|
|
41
|
+
console.log(`\n::${level} file=${escapedFilename},line=${line},col=${column}::${fullMessage}`);
|
|
42
|
+
}
|
|
43
|
+
escapeMessage(string) {
|
|
44
|
+
return string.replace(new RegExp(Object.keys(GitHubActionsFormatter.MESSAGE_ESCAPE_MAP).map(k => k.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|'), 'g'), match => GitHubActionsFormatter.MESSAGE_ESCAPE_MAP[match]);
|
|
45
|
+
}
|
|
46
|
+
escapeParam(string) {
|
|
47
|
+
return string.replace(new RegExp(Object.keys(GitHubActionsFormatter.PARAM_ESCAPE_MAP).map(k => k.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|'), 'g'), match => GitHubActionsFormatter.PARAM_ESCAPE_MAP[match]);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=github-actions-formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-actions-formatter.js","sourceRoot":"","sources":["../../../../src/cli/formatters/github-actions-formatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAKnD,uFAAuF;AACvF,MAAM,OAAO,sBAAuB,SAAQ,aAAa;IAC/C,MAAM,CAAU,kBAAkB,GAA2B;QACnE,GAAG,EAAE,KAAK;QACV,IAAI,EAAE,KAAK;QACX,IAAI,EAAE,KAAK;KACZ,CAAA;IAEO,MAAM,CAAU,gBAAgB,GAA2B;QACjE,GAAG,EAAE,KAAK;QACV,IAAI,EAAE,KAAK;QACX,IAAI,EAAE,KAAK;QACX,GAAG,EAAE,KAAK;QACV,GAAG,EAAE,KAAK;KACX,CAAA;IAED,KAAK,CAAC,MAAM,CAAC,cAA+B;QAC1C,KAAK,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,cAAc,EAAE,CAAC;YACnD,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QAC1C,CAAC;QAED,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,EAAE,CAAA;QACf,CAAC;IACH,CAAC;IAED,UAAU,CAAC,QAAgB,EAAE,WAAyB;QACpD,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACrC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QAC7C,CAAC;IACH,CAAC;IAED,oCAAoC;IACpC,yDAAyD;IACzD,EAAE;IACM,gBAAgB,CAAC,QAAgB,EAAE,UAAsB;QAC/D,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAA;QACnE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAA;QAElD,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAA;QAClD,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;QAEtD,IAAI,WAAW,GAAG,OAAO,CAAA;QAEzB,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;YACpB,WAAW,IAAI,KAAK,UAAU,CAAC,IAAI,GAAG,CAAA;QACxC,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,SAAS,eAAe,SAAS,IAAI,QAAQ,MAAM,KAAK,WAAW,EAAE,CAAC,CAAA;IAChG,CAAC;IAEO,aAAa,CAAC,MAAc;QAClC,OAAO,MAAM,CAAC,OAAO,CACnB,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EACpI,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAC1D,CAAA;IACH,CAAC;IAEO,WAAW,CAAC,MAAc;QAChC,OAAO,MAAM,CAAC,OAAO,CACnB,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAClI,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,KAAK,CAAC,CACxD,CAAA;IACH,CAAC"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { BaseFormatter } from "./base-formatter.js";
|
|
2
2
|
export { SimpleFormatter } from "./simple-formatter.js";
|
|
3
3
|
export { DetailedFormatter } from "./detailed-formatter.js";
|
|
4
|
+
export { JSONFormatter } from "./json-formatter.js";
|
|
5
|
+
export { GitHubActionsFormatter } from "./github-actions-formatter.js";
|
|
4
6
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/cli/formatters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/cli/formatters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAmB,MAAM,qBAAqB,CAAA;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { BaseFormatter } from "./base-formatter.js";
|
|
2
|
+
export class JSONFormatter extends BaseFormatter {
|
|
3
|
+
async format(allOffenses) {
|
|
4
|
+
const jsonOffenses = allOffenses.map(({ filename, offense }) => ({
|
|
5
|
+
filename,
|
|
6
|
+
message: offense.message,
|
|
7
|
+
location: offense.location.toJSON(),
|
|
8
|
+
severity: offense.severity,
|
|
9
|
+
code: offense.code,
|
|
10
|
+
source: offense.source
|
|
11
|
+
}));
|
|
12
|
+
const output = {
|
|
13
|
+
offenses: jsonOffenses,
|
|
14
|
+
summary: null,
|
|
15
|
+
timing: null,
|
|
16
|
+
completed: true,
|
|
17
|
+
clean: jsonOffenses.length === 0,
|
|
18
|
+
message: null
|
|
19
|
+
};
|
|
20
|
+
console.log(JSON.stringify(output, null, 2));
|
|
21
|
+
}
|
|
22
|
+
async formatWithSummary(allOffenses, options) {
|
|
23
|
+
const jsonOffenses = allOffenses.map(({ filename, offense }) => ({
|
|
24
|
+
filename,
|
|
25
|
+
message: offense.message,
|
|
26
|
+
location: offense.location.toJSON(),
|
|
27
|
+
severity: offense.severity,
|
|
28
|
+
code: offense.code,
|
|
29
|
+
source: offense.source
|
|
30
|
+
}));
|
|
31
|
+
const summary = {
|
|
32
|
+
filesChecked: options.files.length,
|
|
33
|
+
filesWithOffenses: options.filesWithOffenses,
|
|
34
|
+
totalErrors: options.totalErrors,
|
|
35
|
+
totalWarnings: options.totalWarnings,
|
|
36
|
+
totalOffenses: options.totalErrors + options.totalWarnings,
|
|
37
|
+
ruleCount: options.ruleCount
|
|
38
|
+
};
|
|
39
|
+
const output = {
|
|
40
|
+
offenses: jsonOffenses,
|
|
41
|
+
summary,
|
|
42
|
+
timing: null,
|
|
43
|
+
completed: true,
|
|
44
|
+
clean: options.totalErrors === 0 && options.totalWarnings === 0,
|
|
45
|
+
message: null
|
|
46
|
+
};
|
|
47
|
+
const duration = Date.now() - options.startTime;
|
|
48
|
+
output.timing = options.showTiming ? {
|
|
49
|
+
startTime: options.startDate.toISOString(),
|
|
50
|
+
duration: duration
|
|
51
|
+
} : null;
|
|
52
|
+
console.log(JSON.stringify(output, null, 2));
|
|
53
|
+
}
|
|
54
|
+
formatFile(_filename, _offenses) {
|
|
55
|
+
// Not used in JSON formatter, everything is handled in format()
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=json-formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-formatter.js","sourceRoot":"","sources":["../../../../src/cli/formatters/json-formatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AA2CnD,MAAM,OAAO,aAAc,SAAQ,aAAa;IAC9C,KAAK,CAAC,MAAM,CAAC,WAA4B;QACvC,MAAM,YAAY,GAAkB,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;YAC9E,QAAQ;YACR,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE;YACnC,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC,CAAA;QAEH,MAAM,MAAM,GAAe;YACzB,QAAQ,EAAE,YAAY;YACtB,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,IAAI;YACZ,SAAS,EAAE,IAAI;YACf,KAAK,EAAE,YAAY,CAAC,MAAM,KAAK,CAAC;YAChC,OAAO,EAAE,IAAI;SACd,CAAA;QAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAC9C,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,WAA4B,EAAE,OAA0B;QAC9E,MAAM,YAAY,GAAkB,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;YAC9E,QAAQ;YACR,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE;YACnC,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC,CAAA;QAEH,MAAM,OAAO,GAAgB;YAC3B,YAAY,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM;YAClC,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;YAC5C,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,aAAa,EAAE,OAAO,CAAC,WAAW,GAAG,OAAO,CAAC,aAAa;YAC1D,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAA;QAED,MAAM,MAAM,GAAe;YACzB,QAAQ,EAAE,YAAY;YACtB,OAAO;YACP,MAAM,EAAE,IAAI;YACZ,SAAS,EAAE,IAAI;YACf,KAAK,EAAE,OAAO,CAAC,WAAW,KAAK,CAAC,IAAI,OAAO,CAAC,aAAa,KAAK,CAAC;YAC/D,OAAO,EAAE,IAAI;SACd,CAAA;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,SAAS,CAAA;QAC/C,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;YACnC,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE;YAC1C,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAC,CAAC,IAAI,CAAA;QAER,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAC9C,CAAC;IAED,UAAU,CAAC,SAAiB,EAAE,SAAuB;QACnD,gEAAgE;IAClE,CAAC;CACF"}
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
import { colorize } from "@herb-tools/highlighter";
|
|
2
2
|
import { BaseFormatter } from "./base-formatter.js";
|
|
3
3
|
export class SimpleFormatter extends BaseFormatter {
|
|
4
|
-
async format(
|
|
5
|
-
if (
|
|
4
|
+
async format(allOffenses) {
|
|
5
|
+
if (allOffenses.length === 0)
|
|
6
6
|
return;
|
|
7
|
-
const
|
|
8
|
-
for (const { filename,
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
const groupedOffenses = new Map();
|
|
8
|
+
for (const { filename, offense } of allOffenses) {
|
|
9
|
+
const offenses = groupedOffenses.get(filename) || [];
|
|
10
|
+
offenses.push(offense);
|
|
11
|
+
groupedOffenses.set(filename, offenses);
|
|
12
12
|
}
|
|
13
|
-
for (const [filename,
|
|
13
|
+
for (const [filename, offenses] of groupedOffenses) {
|
|
14
14
|
console.log("");
|
|
15
|
-
this.formatFile(filename,
|
|
15
|
+
this.formatFile(filename, offenses);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
formatFile(filename,
|
|
18
|
+
formatFile(filename, offenses) {
|
|
19
19
|
console.log(`${colorize(filename, "cyan")}:`);
|
|
20
|
-
for (const
|
|
21
|
-
const isError =
|
|
20
|
+
for (const offense of offenses) {
|
|
21
|
+
const isError = offense.severity === "error";
|
|
22
22
|
const severity = isError ? colorize("✗", "brightRed") : colorize("⚠", "brightYellow");
|
|
23
|
-
const rule = colorize(`(${
|
|
24
|
-
const locationString = `${
|
|
23
|
+
const rule = colorize(`(${offense.code})`, "blue");
|
|
24
|
+
const locationString = `${offense.location.start.line}:${offense.location.start.column}`;
|
|
25
25
|
const paddedLocation = locationString.padEnd(4); // Pad to 4 characters for alignment
|
|
26
|
-
console.log(` ${colorize(paddedLocation, "gray")} ${severity} ${
|
|
26
|
+
console.log(` ${colorize(paddedLocation, "gray")} ${severity} ${offense.message} ${rule}`);
|
|
27
27
|
}
|
|
28
28
|
console.log("");
|
|
29
29
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simple-formatter.js","sourceRoot":"","sources":["../../../../src/cli/formatters/simple-formatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAElD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAKnD,MAAM,OAAO,eAAgB,SAAQ,aAAa;IAChD,KAAK,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"simple-formatter.js","sourceRoot":"","sources":["../../../../src/cli/formatters/simple-formatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAElD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAKnD,MAAM,OAAO,eAAgB,SAAQ,aAAa;IAChD,KAAK,CAAC,MAAM,CAAC,WAA4B;QACvC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QAEpC,MAAM,eAAe,GAAG,IAAI,GAAG,EAAwB,CAAA;QAEvD,KAAK,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,WAAW,EAAE,CAAC;YAChD,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAA;YACpD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACtB,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;QACzC,CAAC;QAED,KAAK,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,eAAe,EAAE,CAAC;YACnD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YACf,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;QACrC,CAAC;IACH,CAAC;IAED,UAAU,CAAC,QAAgB,EAAE,QAAsB;QACjD,OAAO,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,CAAA;QAE7C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAA;YAC5C,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC,CAAA;YACrF,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,OAAO,CAAC,IAAI,GAAG,EAAE,MAAM,CAAC,CAAA;YAClD,MAAM,cAAc,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,CAAA;YACxF,MAAM,cAAc,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA,CAAC,oCAAoC;YAEpF,OAAO,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,IAAI,QAAQ,IAAI,OAAO,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC,CAAA;QAC7F,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACjB,CAAC;CACF"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { SummaryReporter } from "./summary-reporter.js";
|
|
2
|
+
import { SimpleFormatter, DetailedFormatter, GitHubActionsFormatter } from "./formatters/index.js";
|
|
3
|
+
export class OutputManager {
|
|
4
|
+
summaryReporter = new SummaryReporter();
|
|
5
|
+
/**
|
|
6
|
+
* Output successful lint results
|
|
7
|
+
*/
|
|
8
|
+
async outputResults(results, options) {
|
|
9
|
+
const { allOffenses, files, totalErrors, totalWarnings, filesWithOffenses, ruleCount, ruleOffenses } = results;
|
|
10
|
+
if (options.formatOption === "github") {
|
|
11
|
+
const formatter = new GitHubActionsFormatter();
|
|
12
|
+
await formatter.format(allOffenses);
|
|
13
|
+
}
|
|
14
|
+
else if (options.formatOption === "json") {
|
|
15
|
+
const output = {
|
|
16
|
+
offenses: allOffenses.map(({ filename, offense }) => ({
|
|
17
|
+
filename,
|
|
18
|
+
message: offense.message,
|
|
19
|
+
location: offense.location.toJSON(),
|
|
20
|
+
severity: offense.severity,
|
|
21
|
+
code: offense.code,
|
|
22
|
+
source: offense.source
|
|
23
|
+
})),
|
|
24
|
+
summary: {
|
|
25
|
+
filesChecked: files.length,
|
|
26
|
+
filesWithOffenses,
|
|
27
|
+
totalErrors,
|
|
28
|
+
totalWarnings,
|
|
29
|
+
totalOffenses: totalErrors + totalWarnings,
|
|
30
|
+
ruleCount
|
|
31
|
+
},
|
|
32
|
+
timing: null,
|
|
33
|
+
completed: true,
|
|
34
|
+
clean: totalErrors === 0 && totalWarnings === 0,
|
|
35
|
+
message: null
|
|
36
|
+
};
|
|
37
|
+
const duration = Date.now() - options.startTime;
|
|
38
|
+
output.timing = options.showTiming ? {
|
|
39
|
+
startTime: options.startDate.toISOString(),
|
|
40
|
+
duration: duration
|
|
41
|
+
} : null;
|
|
42
|
+
console.log(JSON.stringify(output, null, 2));
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
const formatter = options.formatOption === "simple"
|
|
46
|
+
? new SimpleFormatter()
|
|
47
|
+
: new DetailedFormatter(options.theme, options.wrapLines, options.truncateLines);
|
|
48
|
+
await formatter.format(allOffenses, files.length === 1);
|
|
49
|
+
this.summaryReporter.displayMostViolatedRules(ruleOffenses);
|
|
50
|
+
this.summaryReporter.displaySummary({
|
|
51
|
+
files,
|
|
52
|
+
totalErrors,
|
|
53
|
+
totalWarnings,
|
|
54
|
+
filesWithOffenses,
|
|
55
|
+
ruleCount,
|
|
56
|
+
startTime: options.startTime,
|
|
57
|
+
startDate: options.startDate,
|
|
58
|
+
showTiming: options.showTiming,
|
|
59
|
+
ruleOffenses
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Output informational message (like "no files found")
|
|
65
|
+
*/
|
|
66
|
+
outputInfo(message, options) {
|
|
67
|
+
if (options.formatOption === "github") {
|
|
68
|
+
// GitHub Actions format doesn't output anything for info messages
|
|
69
|
+
}
|
|
70
|
+
else if (options.formatOption === "json") {
|
|
71
|
+
const output = {
|
|
72
|
+
offenses: [],
|
|
73
|
+
summary: {
|
|
74
|
+
filesChecked: 0,
|
|
75
|
+
filesWithOffenses: 0,
|
|
76
|
+
totalErrors: 0,
|
|
77
|
+
totalWarnings: 0,
|
|
78
|
+
totalOffenses: 0,
|
|
79
|
+
ruleCount: 0
|
|
80
|
+
},
|
|
81
|
+
timing: null,
|
|
82
|
+
completed: false,
|
|
83
|
+
clean: null,
|
|
84
|
+
message
|
|
85
|
+
};
|
|
86
|
+
const duration = Date.now() - options.startTime;
|
|
87
|
+
output.timing = options.showTiming ? {
|
|
88
|
+
startTime: options.startDate.toISOString(),
|
|
89
|
+
duration: duration
|
|
90
|
+
} : null;
|
|
91
|
+
console.log(JSON.stringify(output, null, 2));
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
console.log(message);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Output error message
|
|
99
|
+
*/
|
|
100
|
+
outputError(message, options) {
|
|
101
|
+
if (options.formatOption === "github") {
|
|
102
|
+
console.log(`::error::${message}`);
|
|
103
|
+
}
|
|
104
|
+
else if (options.formatOption === "json") {
|
|
105
|
+
const output = {
|
|
106
|
+
offenses: [],
|
|
107
|
+
summary: null,
|
|
108
|
+
timing: null,
|
|
109
|
+
completed: false,
|
|
110
|
+
clean: null,
|
|
111
|
+
message
|
|
112
|
+
};
|
|
113
|
+
console.log(JSON.stringify(output, null, 2));
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
console.error(message);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=output-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-manager.js","sourceRoot":"","sources":["../../../src/cli/output-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,22 +4,22 @@ export class SummaryReporter {
|
|
|
4
4
|
return count === 1 ? singular : (plural || `${singular}s`);
|
|
5
5
|
}
|
|
6
6
|
displaySummary(data) {
|
|
7
|
-
const { files, totalErrors, totalWarnings,
|
|
7
|
+
const { files, totalErrors, totalWarnings, filesWithOffenses, ruleCount, startTime, startDate, showTiming } = data;
|
|
8
8
|
console.log("\n");
|
|
9
9
|
console.log(` ${colorize("Summary:", "bold")}`);
|
|
10
10
|
// Calculate padding for alignment
|
|
11
|
-
const labelWidth = 12; // Width for the longest label "
|
|
11
|
+
const labelWidth = 12; // Width for the longest label "Offenses"
|
|
12
12
|
const pad = (label) => label.padEnd(labelWidth);
|
|
13
13
|
// Checked summary
|
|
14
14
|
console.log(` ${colorize(pad("Checked"), "gray")} ${colorize(`${files.length} ${this.pluralize(files.length, "file")}`, "cyan")}`);
|
|
15
15
|
// Files summary (for multiple files)
|
|
16
16
|
if (files.length > 1) {
|
|
17
17
|
const filesChecked = files.length;
|
|
18
|
-
const filesClean = filesChecked -
|
|
18
|
+
const filesClean = filesChecked - filesWithOffenses;
|
|
19
19
|
let filesSummary = "";
|
|
20
20
|
let shouldDim = false;
|
|
21
|
-
if (
|
|
22
|
-
filesSummary = `${colorize(colorize(`${
|
|
21
|
+
if (filesWithOffenses > 0) {
|
|
22
|
+
filesSummary = `${colorize(colorize(`${filesWithOffenses} with offenses`, "brightRed"), "bold")} | ${colorize(colorize(`${filesClean} clean`, "green"), "bold")} ${colorize(colorize(`(${filesChecked} total)`, "gray"), "dim")}`;
|
|
23
23
|
}
|
|
24
24
|
else {
|
|
25
25
|
filesSummary = `${colorize(colorize(`${filesChecked} clean`, "green"), "bold")} ${colorize(colorize(`(${filesChecked} total)`, "gray"), "dim")}`;
|
|
@@ -32,8 +32,8 @@ export class SummaryReporter {
|
|
|
32
32
|
console.log(` ${colorize(pad("Files"), "gray")} ${filesSummary}`);
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
-
//
|
|
36
|
-
let
|
|
35
|
+
// Offenses summary with file count
|
|
36
|
+
let offensesSummary = "";
|
|
37
37
|
const parts = [];
|
|
38
38
|
// Build the main part with errors and warnings
|
|
39
39
|
if (totalErrors > 0) {
|
|
@@ -47,19 +47,19 @@ export class SummaryReporter {
|
|
|
47
47
|
parts.push(colorize(colorize(`${totalWarnings} ${this.pluralize(totalWarnings, "warning")}`, "green"), "bold"));
|
|
48
48
|
}
|
|
49
49
|
if (parts.length === 0) {
|
|
50
|
-
|
|
50
|
+
offensesSummary = colorize(colorize("0 offenses", "green"), "bold");
|
|
51
51
|
}
|
|
52
52
|
else {
|
|
53
|
-
|
|
53
|
+
offensesSummary = parts.join(" | ");
|
|
54
54
|
// Add total count and file count
|
|
55
55
|
let detailText = "";
|
|
56
|
-
const
|
|
57
|
-
if (
|
|
58
|
-
detailText = `${
|
|
56
|
+
const totalOffenses = totalErrors + totalWarnings;
|
|
57
|
+
if (filesWithOffenses > 0) {
|
|
58
|
+
detailText = `${totalOffenses} ${this.pluralize(totalOffenses, "offense")} across ${filesWithOffenses} ${this.pluralize(filesWithOffenses, "file")}`;
|
|
59
59
|
}
|
|
60
|
-
|
|
60
|
+
offensesSummary += ` ${colorize(colorize(`(${detailText})`, "gray"), "dim")}`;
|
|
61
61
|
}
|
|
62
|
-
console.log(` ${colorize(pad("
|
|
62
|
+
console.log(` ${colorize(pad("Offenses"), "gray")} ${offensesSummary}`);
|
|
63
63
|
// Timing information (if enabled)
|
|
64
64
|
if (showTiming) {
|
|
65
65
|
const duration = Date.now() - startTime;
|
|
@@ -68,28 +68,28 @@ export class SummaryReporter {
|
|
|
68
68
|
console.log(` ${colorize(pad("Duration"), "gray")} ${colorize(`${duration}ms`, "cyan")} ${colorize(colorize(`(${ruleCount} ${this.pluralize(ruleCount, "rule")})`, "gray"), "dim")}`);
|
|
69
69
|
}
|
|
70
70
|
// Success message for all files clean
|
|
71
|
-
if (
|
|
71
|
+
if (filesWithOffenses === 0 && files.length > 1) {
|
|
72
72
|
console.log("");
|
|
73
73
|
console.log(` ${colorize("✓", "brightGreen")} ${colorize("All files are clean!", "green")}`);
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
|
-
displayMostViolatedRules(
|
|
77
|
-
if (
|
|
76
|
+
displayMostViolatedRules(ruleOffenses, limit = 5) {
|
|
77
|
+
if (ruleOffenses.size === 0)
|
|
78
78
|
return;
|
|
79
|
-
const allRules = Array.from(
|
|
79
|
+
const allRules = Array.from(ruleOffenses.entries()).sort((a, b) => b[1].count - a[1].count);
|
|
80
80
|
const displayedRules = allRules.slice(0, limit);
|
|
81
81
|
const remainingRules = allRules.slice(limit);
|
|
82
|
-
const title =
|
|
82
|
+
const title = ruleOffenses.size <= limit ? "Rule offenses:" : "Most frequent rule offenses:";
|
|
83
83
|
console.log(` ${colorize(title, "bold")}`);
|
|
84
84
|
for (const [rule, data] of displayedRules) {
|
|
85
85
|
const fileCount = data.files.size;
|
|
86
|
-
const countText = `(${data.count} ${this.pluralize(data.count, "
|
|
86
|
+
const countText = `(${data.count} ${this.pluralize(data.count, "offense")} in ${fileCount} ${this.pluralize(fileCount, "file")})`;
|
|
87
87
|
console.log(` ${colorize(rule, "gray")} ${colorize(colorize(countText, "gray"), "dim")}`);
|
|
88
88
|
}
|
|
89
89
|
if (remainingRules.length > 0) {
|
|
90
|
-
const
|
|
90
|
+
const remainingOffenseCount = remainingRules.reduce((sum, [_, data]) => sum + data.count, 0);
|
|
91
91
|
const remainingRuleCount = remainingRules.length;
|
|
92
|
-
console.log(colorize(colorize(`\n ...and ${remainingRuleCount} more ${this.pluralize(remainingRuleCount, "rule")} with ${
|
|
92
|
+
console.log(colorize(colorize(`\n ...and ${remainingRuleCount} more ${this.pluralize(remainingRuleCount, "rule")} with ${remainingOffenseCount} ${this.pluralize(remainingOffenseCount, "offense")}`, "gray"), "dim"));
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summary-reporter.js","sourceRoot":"","sources":["../../../src/cli/summary-reporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAclD,MAAM,OAAO,eAAe;IAClB,SAAS,CAAC,KAAa,EAAE,QAAgB,EAAE,MAAe;QAChE,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,QAAQ,GAAG,CAAC,CAAA;IAC5D,CAAC;IAED,cAAc,CAAC,IAAiB;QAC9B,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"summary-reporter.js","sourceRoot":"","sources":["../../../src/cli/summary-reporter.ts"],"names":[],"mappings":"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"}
|