@herb-tools/linter 0.6.1 → 0.7.1
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 +60 -16
- package/dist/herb-lint.js +364 -181
- package/dist/herb-lint.js.map +1 -1
- package/dist/index.cjs +321 -100
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +270 -89
- package/dist/index.js.map +1 -1
- package/dist/package.json +11 -5
- package/dist/src/cli/argument-parser.js +11 -6
- package/dist/src/cli/argument-parser.js.map +1 -1
- package/dist/src/cli/file-processor.js +5 -6
- package/dist/src/cli/file-processor.js.map +1 -1
- package/dist/src/cli/formatters/detailed-formatter.js +3 -5
- package/dist/src/cli/formatters/detailed-formatter.js.map +1 -1
- package/dist/src/cli/formatters/github-actions-formatter.js +55 -11
- package/dist/src/cli/formatters/github-actions-formatter.js.map +1 -1
- package/dist/src/cli/index.js +1 -0
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/cli/output-manager.js +23 -5
- package/dist/src/cli/output-manager.js.map +1 -1
- package/dist/src/cli/summary-reporter.js +2 -11
- package/dist/src/cli/summary-reporter.js.map +1 -1
- package/dist/src/cli.js +88 -4
- package/dist/src/cli.js.map +1 -1
- package/dist/src/default-rules.js +8 -4
- package/dist/src/default-rules.js.map +1 -1
- package/dist/src/linter.js.map +1 -1
- package/dist/src/rules/erb-prefer-image-tag-helper.js +1 -1
- package/dist/src/rules/erb-prefer-image-tag-helper.js.map +1 -1
- package/dist/src/rules/html-boolean-attributes-no-value.js +8 -8
- package/dist/src/rules/html-boolean-attributes-no-value.js.map +1 -1
- package/dist/src/rules/html-no-empty-attributes.js +56 -0
- package/dist/src/rules/html-no-empty-attributes.js.map +1 -0
- package/dist/src/rules/html-no-positive-tab-index.js +1 -1
- package/dist/src/rules/html-no-positive-tab-index.js.map +1 -1
- package/dist/src/rules/html-no-underscores-in-attribute-names.js +36 -0
- package/dist/src/rules/html-no-underscores-in-attribute-names.js.map +1 -0
- package/dist/src/rules/index.js +3 -0
- package/dist/src/rules/index.js.map +1 -1
- package/dist/src/rules/rule-utils.js +11 -7
- package/dist/src/rules/rule-utils.js.map +1 -1
- 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 -1
- package/dist/types/cli/formatters/github-actions-formatter.d.ts +6 -1
- package/dist/types/cli/index.d.ts +1 -0
- package/dist/types/cli/output-manager.d.ts +1 -0
- package/dist/types/cli.d.ts +20 -5
- package/dist/types/linter.d.ts +7 -7
- package/dist/types/rules/html-no-empty-attributes.d.ts +7 -0
- package/dist/types/rules/html-no-underscores-in-attribute-names.d.ts +7 -0
- package/dist/types/rules/index.d.ts +3 -0
- package/dist/types/rules/rule-utils.d.ts +7 -5
- package/dist/types/src/cli/argument-parser.d.ts +2 -1
- package/dist/types/src/cli/file-processor.d.ts +6 -1
- package/dist/types/src/cli/formatters/github-actions-formatter.d.ts +6 -1
- package/dist/types/src/cli/index.d.ts +1 -0
- package/dist/types/src/cli/output-manager.d.ts +1 -0
- package/dist/types/src/cli.d.ts +20 -5
- package/dist/types/src/linter.d.ts +7 -7
- package/dist/types/src/rules/html-no-empty-attributes.d.ts +7 -0
- package/dist/types/src/rules/html-no-underscores-in-attribute-names.d.ts +7 -0
- package/dist/types/src/rules/index.d.ts +3 -0
- package/dist/types/src/rules/rule-utils.d.ts +7 -5
- package/docs/rules/README.md +2 -0
- package/docs/rules/html-img-require-alt.md +0 -2
- package/docs/rules/html-no-empty-attributes.md +77 -0
- package/docs/rules/html-no-underscores-in-attribute-names.md +45 -0
- package/package.json +11 -5
- package/src/cli/argument-parser.ts +15 -7
- package/src/cli/file-processor.ts +11 -7
- package/src/cli/formatters/detailed-formatter.ts +5 -7
- package/src/cli/formatters/github-actions-formatter.ts +64 -11
- package/src/cli/index.ts +2 -0
- package/src/cli/output-manager.ts +27 -5
- package/src/cli/summary-reporter.ts +3 -11
- package/src/cli.ts +125 -20
- package/src/default-rules.ts +8 -4
- package/src/linter.ts +6 -6
- package/src/rules/erb-no-silent-tag-in-attribute-name.ts +1 -1
- package/src/rules/erb-prefer-image-tag-helper.ts +2 -2
- package/src/rules/erb-require-whitespace-inside-tags.ts +2 -2
- package/src/rules/html-attribute-double-quotes.ts +1 -1
- package/src/rules/html-boolean-attributes-no-value.ts +9 -11
- package/src/rules/html-no-empty-attributes.ts +75 -0
- package/src/rules/html-no-positive-tab-index.ts +1 -1
- package/src/rules/html-no-underscores-in-attribute-names.ts +58 -0
- package/src/rules/html-tag-name-lowercase.ts +1 -1
- package/src/rules/index.ts +3 -0
- package/src/rules/rule-utils.ts +15 -11
- package/src/rules/svg-tag-name-capitalization.ts +2 -2
|
@@ -17,10 +17,11 @@ export class ArgumentParser {
|
|
|
17
17
|
Options:
|
|
18
18
|
-h, --help show help
|
|
19
19
|
-v, --version show version
|
|
20
|
-
--format output format (simple|detailed|json
|
|
20
|
+
--format output format (simple|detailed|json) [default: detailed]
|
|
21
21
|
--simple use simple output format (shortcut for --format simple)
|
|
22
22
|
--json use JSON output format (shortcut for --format json)
|
|
23
|
-
--github
|
|
23
|
+
--github enable GitHub Actions annotations (combines with --format)
|
|
24
|
+
--no-github disable GitHub Actions annotations (even in GitHub Actions environment)
|
|
24
25
|
--theme syntax highlighting theme (${THEME_NAMES.join("|")}) or path to custom theme file [default: ${DEFAULT_THEME}]
|
|
25
26
|
--no-color disable colored output
|
|
26
27
|
--no-timing hide timing information
|
|
@@ -37,6 +38,7 @@ export class ArgumentParser {
|
|
|
37
38
|
simple: { type: "boolean" },
|
|
38
39
|
json: { type: "boolean" },
|
|
39
40
|
github: { type: "boolean" },
|
|
41
|
+
"no-github": { type: "boolean" },
|
|
40
42
|
theme: { type: "string" },
|
|
41
43
|
"no-color": { type: "boolean" },
|
|
42
44
|
"no-timing": { type: "boolean" },
|
|
@@ -54,8 +56,9 @@ export class ArgumentParser {
|
|
|
54
56
|
console.log(` ${name}@${version}, ${Herb.version}`.split(", ").join("\n "));
|
|
55
57
|
process.exit(0);
|
|
56
58
|
}
|
|
59
|
+
const isGitHubActions = process.env.GITHUB_ACTIONS === "true";
|
|
57
60
|
let formatOption = "detailed";
|
|
58
|
-
if (values.format && (values.format === "detailed" || values.format === "simple" || values.format === "json"
|
|
61
|
+
if (values.format && (values.format === "detailed" || values.format === "simple" || values.format === "json")) {
|
|
59
62
|
formatOption = values.format;
|
|
60
63
|
}
|
|
61
64
|
if (values.simple) {
|
|
@@ -64,8 +67,10 @@ export class ArgumentParser {
|
|
|
64
67
|
if (values.json) {
|
|
65
68
|
formatOption = "json";
|
|
66
69
|
}
|
|
67
|
-
|
|
68
|
-
|
|
70
|
+
const useGitHubActions = (values.github || isGitHubActions) && !values["no-github"];
|
|
71
|
+
if (useGitHubActions && formatOption === "json") {
|
|
72
|
+
console.error("Error: --github cannot be used with --json format. JSON format is already structured for programmatic consumption.");
|
|
73
|
+
process.exit(1);
|
|
69
74
|
}
|
|
70
75
|
if (values["no-color"]) {
|
|
71
76
|
process.env.NO_COLOR = "1";
|
|
@@ -83,7 +88,7 @@ export class ArgumentParser {
|
|
|
83
88
|
}
|
|
84
89
|
const theme = values.theme || DEFAULT_THEME;
|
|
85
90
|
const pattern = this.getFilePattern(positionals);
|
|
86
|
-
return { pattern, formatOption, showTiming, theme, wrapLines, truncateLines };
|
|
91
|
+
return { pattern, formatOption, showTiming, theme, wrapLines, truncateLines, useGitHubActions };
|
|
87
92
|
}
|
|
88
93
|
getFilePattern(positionals) {
|
|
89
94
|
let pattern = positionals.length > 0 ? positionals[0] : "**/*.html.erb";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"argument-parser.js","sourceRoot":"","sources":["../../../src/cli/argument-parser.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAA;AAE3B,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAA;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAA;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAA;AAE5C,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAGpE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"argument-parser.js","sourceRoot":"","sources":["../../../src/cli/argument-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,7 @@ 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, formatOption = 'detailed') {
|
|
8
|
+
async processFiles(files, formatOption = 'detailed', context) {
|
|
9
9
|
let totalErrors = 0;
|
|
10
10
|
let totalWarnings = 0;
|
|
11
11
|
let filesWithOffenses = 0;
|
|
@@ -13,17 +13,16 @@ export class FileProcessor {
|
|
|
13
13
|
const allOffenses = [];
|
|
14
14
|
const ruleOffenses = new Map();
|
|
15
15
|
for (const filename of files) {
|
|
16
|
-
const filePath = resolve(filename);
|
|
16
|
+
const filePath = context?.projectPath ? resolve(context.projectPath, filename) : 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
|
-
if (formatOption !== 'json'
|
|
20
|
+
if (formatOption !== 'json') {
|
|
21
21
|
console.error(`${colorize(filename, "cyan")} - ${colorize("Parse errors:", "brightRed")}`);
|
|
22
22
|
for (const error of parseResult.errors) {
|
|
23
23
|
console.error(` ${colorize("✗", "brightRed")} ${error.message}`);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
-
// Add parse errors to offenses for JSON output
|
|
27
26
|
for (const error of parseResult.errors) {
|
|
28
27
|
allOffenses.push({ filename, offense: error, content });
|
|
29
28
|
}
|
|
@@ -39,7 +38,7 @@ export class FileProcessor {
|
|
|
39
38
|
ruleCount = this.linter.getRuleCount();
|
|
40
39
|
}
|
|
41
40
|
if (lintResult.offenses.length === 0) {
|
|
42
|
-
if (files.length === 1 && formatOption !== 'json'
|
|
41
|
+
if (files.length === 1 && formatOption !== 'json') {
|
|
43
42
|
console.log(`${colorize("✓", "brightGreen")} ${colorize(filename, "cyan")} - ${colorize("No issues found", "green")}`);
|
|
44
43
|
}
|
|
45
44
|
}
|
|
@@ -56,7 +55,7 @@ export class FileProcessor {
|
|
|
56
55
|
filesWithOffenses++;
|
|
57
56
|
}
|
|
58
57
|
}
|
|
59
|
-
return { totalErrors, totalWarnings, filesWithOffenses, ruleCount, allOffenses, ruleOffenses };
|
|
58
|
+
return { totalErrors, totalWarnings, filesWithOffenses, ruleCount, allOffenses, ruleOffenses, context };
|
|
60
59
|
}
|
|
61
60
|
}
|
|
62
61
|
//# 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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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { colorize, Highlighter, DEFAULT_THEME } from "@herb-tools/highlighter";
|
|
2
2
|
import { BaseFormatter } from "./base-formatter.js";
|
|
3
|
+
import { LineWrapper } from "@herb-tools/highlighter";
|
|
3
4
|
export class DetailedFormatter extends BaseFormatter {
|
|
4
5
|
highlighter = null;
|
|
5
6
|
theme;
|
|
@@ -19,12 +20,11 @@ export class DetailedFormatter extends BaseFormatter {
|
|
|
19
20
|
await this.highlighter.initialize();
|
|
20
21
|
}
|
|
21
22
|
if (isSingleFile) {
|
|
22
|
-
// For single file, use inline diagnostics with syntax highlighting
|
|
23
23
|
const { filename, content } = allOffenses[0];
|
|
24
24
|
const diagnostics = allOffenses.map(item => item.offense);
|
|
25
25
|
const highlighted = this.highlighter.highlight(filename, content, {
|
|
26
26
|
diagnostics: diagnostics,
|
|
27
|
-
splitDiagnostics: true,
|
|
27
|
+
splitDiagnostics: true,
|
|
28
28
|
contextLines: 2,
|
|
29
29
|
wrapLines: this.wrapLines,
|
|
30
30
|
truncateLines: this.truncateLines
|
|
@@ -32,7 +32,6 @@ export class DetailedFormatter extends BaseFormatter {
|
|
|
32
32
|
console.log(`\n${highlighted}`);
|
|
33
33
|
}
|
|
34
34
|
else {
|
|
35
|
-
// For multiple files, show individual diagnostics with syntax highlighting
|
|
36
35
|
const totalMessageCount = allOffenses.length;
|
|
37
36
|
for (let i = 0; i < allOffenses.length; i++) {
|
|
38
37
|
const { filename, offense, content } = allOffenses[i];
|
|
@@ -42,7 +41,7 @@ export class DetailedFormatter extends BaseFormatter {
|
|
|
42
41
|
truncateLines: this.truncateLines
|
|
43
42
|
});
|
|
44
43
|
console.log(`\n${formatted}`);
|
|
45
|
-
const width =
|
|
44
|
+
const width = LineWrapper.getTerminalWidth();
|
|
46
45
|
const progressText = `[${i + 1}/${totalMessageCount}]`;
|
|
47
46
|
const rightPadding = 16;
|
|
48
47
|
const separatorLength = Math.max(0, width - progressText.length - 1 - rightPadding);
|
|
@@ -55,7 +54,6 @@ export class DetailedFormatter extends BaseFormatter {
|
|
|
55
54
|
}
|
|
56
55
|
}
|
|
57
56
|
formatFile(_filename, _offenses) {
|
|
58
|
-
// Not used in detailed formatter
|
|
59
57
|
throw new Error("formatFile is not implemented for DetailedFormatter");
|
|
60
58
|
}
|
|
61
59
|
}
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"detailed-formatter.js","sourceRoot":"","sources":["../../../../src/cli/formatters/detailed-formatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,17 @@
|
|
|
1
|
+
import { Highlighter } from "@herb-tools/highlighter";
|
|
1
2
|
import { BaseFormatter } from "./base-formatter.js";
|
|
3
|
+
import { name, version } from "../../../package.json";
|
|
2
4
|
// https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-commands
|
|
3
5
|
export class GitHubActionsFormatter extends BaseFormatter {
|
|
6
|
+
highlighter;
|
|
7
|
+
wrapLines;
|
|
8
|
+
truncateLines;
|
|
9
|
+
constructor(wrapLines = true, truncateLines = false) {
|
|
10
|
+
super();
|
|
11
|
+
this.wrapLines = wrapLines;
|
|
12
|
+
this.truncateLines = truncateLines;
|
|
13
|
+
this.highlighter = new Highlighter();
|
|
14
|
+
}
|
|
4
15
|
static MESSAGE_ESCAPE_MAP = {
|
|
5
16
|
'%': '%25',
|
|
6
17
|
'\n': '%0A',
|
|
@@ -13,12 +24,36 @@ export class GitHubActionsFormatter extends BaseFormatter {
|
|
|
13
24
|
':': '%3A',
|
|
14
25
|
',': '%2C'
|
|
15
26
|
};
|
|
16
|
-
async format(allDiagnostics) {
|
|
17
|
-
|
|
18
|
-
|
|
27
|
+
async format(allDiagnostics, _isSingleFile = false) {
|
|
28
|
+
await this.formatAnnotations(allDiagnostics);
|
|
29
|
+
}
|
|
30
|
+
async formatAnnotations(allDiagnostics) {
|
|
31
|
+
if (allDiagnostics.length === 0)
|
|
32
|
+
return;
|
|
33
|
+
if (!this.highlighter.initialized) {
|
|
34
|
+
await this.highlighter.initialize();
|
|
19
35
|
}
|
|
20
|
-
|
|
21
|
-
|
|
36
|
+
for (const { filename, offense, content } of allDiagnostics) {
|
|
37
|
+
const originalNoColor = process.env.NO_COLOR;
|
|
38
|
+
process.env.NO_COLOR = "1";
|
|
39
|
+
let plainCodePreview = "";
|
|
40
|
+
try {
|
|
41
|
+
const formatted = this.highlighter.highlightDiagnostic(filename, offense, content, {
|
|
42
|
+
contextLines: 2,
|
|
43
|
+
wrapLines: this.wrapLines,
|
|
44
|
+
truncateLines: this.truncateLines
|
|
45
|
+
});
|
|
46
|
+
plainCodePreview = formatted.split('\n').slice(1).join('\n');
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
if (originalNoColor === undefined) {
|
|
50
|
+
delete process.env.NO_COLOR;
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
process.env.NO_COLOR = originalNoColor;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
this.formatDiagnostic(filename, offense, plainCodePreview);
|
|
22
57
|
}
|
|
23
58
|
}
|
|
24
59
|
formatFile(filename, diagnostics) {
|
|
@@ -27,18 +62,27 @@ export class GitHubActionsFormatter extends BaseFormatter {
|
|
|
27
62
|
}
|
|
28
63
|
}
|
|
29
64
|
// GitHub Actions annotation format:
|
|
30
|
-
// ::{level} file={file},line={line},col={col}::{message}
|
|
65
|
+
// ::{level} file={file},line={line},col={col},title={title}::{message}
|
|
31
66
|
//
|
|
32
|
-
formatDiagnostic(filename, diagnostic) {
|
|
67
|
+
formatDiagnostic(filename, diagnostic, codePreview = "") {
|
|
33
68
|
const level = diagnostic.severity === "error" ? "error" : "warning";
|
|
34
69
|
const { line, column } = diagnostic.location.start;
|
|
35
70
|
const escapedFilename = this.escapeParam(filename);
|
|
36
|
-
|
|
37
|
-
|
|
71
|
+
let message = diagnostic.message;
|
|
72
|
+
if (diagnostic.code) {
|
|
73
|
+
message += ` [${diagnostic.code}]`;
|
|
74
|
+
}
|
|
75
|
+
if (codePreview) {
|
|
76
|
+
message += "\n\n" + codePreview;
|
|
77
|
+
}
|
|
78
|
+
const escapedMessage = this.escapeMessage(message);
|
|
79
|
+
let annotations = `file=${escapedFilename},line=${line},col=${column}`;
|
|
38
80
|
if (diagnostic.code) {
|
|
39
|
-
|
|
81
|
+
const title = `${diagnostic.code} • ${name}@${version}`;
|
|
82
|
+
const escapedTitle = this.escapeParam(title);
|
|
83
|
+
annotations += `,title=${escapedTitle}`;
|
|
40
84
|
}
|
|
41
|
-
console.log(`\n::${level}
|
|
85
|
+
console.log(`\n::${level} ${annotations}::${escapedMessage}`);
|
|
42
86
|
}
|
|
43
87
|
escapeMessage(string) {
|
|
44
88
|
return string.replace(new RegExp(Object.keys(GitHubActionsFormatter.MESSAGE_ESCAPE_MAP).map(k => k.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|'), 'g'), match => GitHubActionsFormatter.MESSAGE_ESCAPE_MAP[match]);
|
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"github-actions-formatter.js","sourceRoot":"","sources":["../../../../src/cli/formatters/github-actions-formatter.ts"],"names":[],"mappings":"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"}
|
package/dist/src/cli/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { ArgumentParser } from "./argument-parser.js";
|
|
2
2
|
export { FileProcessor } from "./file-processor.js";
|
|
3
3
|
export { SummaryReporter } from "./summary-reporter.js";
|
|
4
|
+
export { OutputManager } from "./output-manager.js";
|
|
4
5
|
export * from "./formatters/index.js";
|
|
5
6
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,cAAc,uBAAuB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,cAAc,uBAAuB,CAAA"}
|
|
@@ -7,9 +7,27 @@ export class OutputManager {
|
|
|
7
7
|
*/
|
|
8
8
|
async outputResults(results, options) {
|
|
9
9
|
const { allOffenses, files, totalErrors, totalWarnings, filesWithOffenses, ruleCount, ruleOffenses } = results;
|
|
10
|
-
if (options.
|
|
11
|
-
const
|
|
12
|
-
await
|
|
10
|
+
if (options.useGitHubActions) {
|
|
11
|
+
const githubFormatter = new GitHubActionsFormatter(options.wrapLines, options.truncateLines);
|
|
12
|
+
await githubFormatter.formatAnnotations(allOffenses);
|
|
13
|
+
if (options.formatOption !== "json") {
|
|
14
|
+
const regularFormatter = options.formatOption === "simple"
|
|
15
|
+
? new SimpleFormatter()
|
|
16
|
+
: new DetailedFormatter(options.theme, options.wrapLines, options.truncateLines);
|
|
17
|
+
await regularFormatter.format(allOffenses, files.length === 1);
|
|
18
|
+
this.summaryReporter.displayMostViolatedRules(ruleOffenses);
|
|
19
|
+
this.summaryReporter.displaySummary({
|
|
20
|
+
files,
|
|
21
|
+
totalErrors,
|
|
22
|
+
totalWarnings,
|
|
23
|
+
filesWithOffenses,
|
|
24
|
+
ruleCount,
|
|
25
|
+
startTime: options.startTime,
|
|
26
|
+
startDate: options.startDate,
|
|
27
|
+
showTiming: options.showTiming,
|
|
28
|
+
ruleOffenses
|
|
29
|
+
});
|
|
30
|
+
}
|
|
13
31
|
}
|
|
14
32
|
else if (options.formatOption === "json") {
|
|
15
33
|
const output = {
|
|
@@ -64,7 +82,7 @@ export class OutputManager {
|
|
|
64
82
|
* Output informational message (like "no files found")
|
|
65
83
|
*/
|
|
66
84
|
outputInfo(message, options) {
|
|
67
|
-
if (options.
|
|
85
|
+
if (options.useGitHubActions) {
|
|
68
86
|
// GitHub Actions format doesn't output anything for info messages
|
|
69
87
|
}
|
|
70
88
|
else if (options.formatOption === "json") {
|
|
@@ -98,7 +116,7 @@ export class OutputManager {
|
|
|
98
116
|
* Output error message
|
|
99
117
|
*/
|
|
100
118
|
outputError(message, options) {
|
|
101
|
-
if (options.
|
|
119
|
+
if (options.useGitHubActions) {
|
|
102
120
|
console.log(`::error::${message}`);
|
|
103
121
|
}
|
|
104
122
|
else if (options.formatOption === "json") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output-manager.js","sourceRoot":"","sources":["../../../src/cli/output-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,sBAAsB,EAAmB,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"output-manager.js","sourceRoot":"","sources":["../../../src/cli/output-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,12 +7,9 @@ export class SummaryReporter {
|
|
|
7
7
|
const { files, totalErrors, totalWarnings, filesWithOffenses, ruleCount, startTime, startDate, showTiming } = data;
|
|
8
8
|
console.log("\n");
|
|
9
9
|
console.log(` ${colorize("Summary:", "bold")}`);
|
|
10
|
-
|
|
11
|
-
const labelWidth = 12; // Width for the longest label "Offenses"
|
|
10
|
+
const labelWidth = 12;
|
|
12
11
|
const pad = (label) => label.padEnd(labelWidth);
|
|
13
|
-
// Checked summary
|
|
14
12
|
console.log(` ${colorize(pad("Checked"), "gray")} ${colorize(`${files.length} ${this.pluralize(files.length, "file")}`, "cyan")}`);
|
|
15
|
-
// Files summary (for multiple files)
|
|
16
13
|
if (files.length > 1) {
|
|
17
14
|
const filesChecked = files.length;
|
|
18
15
|
const filesClean = filesChecked - filesWithOffenses;
|
|
@@ -32,10 +29,8 @@ export class SummaryReporter {
|
|
|
32
29
|
console.log(` ${colorize(pad("Files"), "gray")} ${filesSummary}`);
|
|
33
30
|
}
|
|
34
31
|
}
|
|
35
|
-
// Offenses summary with file count
|
|
36
32
|
let offensesSummary = "";
|
|
37
33
|
const parts = [];
|
|
38
|
-
// Build the main part with errors and warnings
|
|
39
34
|
if (totalErrors > 0) {
|
|
40
35
|
parts.push(colorize(colorize(`${totalErrors} ${this.pluralize(totalErrors, "error")}`, "brightRed"), "bold"));
|
|
41
36
|
}
|
|
@@ -43,7 +38,6 @@ export class SummaryReporter {
|
|
|
43
38
|
parts.push(colorize(colorize(`${totalWarnings} ${this.pluralize(totalWarnings, "warning")}`, "brightYellow"), "bold"));
|
|
44
39
|
}
|
|
45
40
|
else if (totalErrors > 0) {
|
|
46
|
-
// Show 0 warnings when there are errors but no warnings
|
|
47
41
|
parts.push(colorize(colorize(`${totalWarnings} ${this.pluralize(totalWarnings, "warning")}`, "green"), "bold"));
|
|
48
42
|
}
|
|
49
43
|
if (parts.length === 0) {
|
|
@@ -51,7 +45,6 @@ export class SummaryReporter {
|
|
|
51
45
|
}
|
|
52
46
|
else {
|
|
53
47
|
offensesSummary = parts.join(" | ");
|
|
54
|
-
// Add total count and file count
|
|
55
48
|
let detailText = "";
|
|
56
49
|
const totalOffenses = totalErrors + totalWarnings;
|
|
57
50
|
if (filesWithOffenses > 0) {
|
|
@@ -60,14 +53,12 @@ export class SummaryReporter {
|
|
|
60
53
|
offensesSummary += ` ${colorize(colorize(`(${detailText})`, "gray"), "dim")}`;
|
|
61
54
|
}
|
|
62
55
|
console.log(` ${colorize(pad("Offenses"), "gray")} ${offensesSummary}`);
|
|
63
|
-
// Timing information (if enabled)
|
|
64
56
|
if (showTiming) {
|
|
65
57
|
const duration = Date.now() - startTime;
|
|
66
|
-
const timeString = startDate.toTimeString().split(' ')[0];
|
|
58
|
+
const timeString = startDate.toTimeString().split(' ')[0];
|
|
67
59
|
console.log(` ${colorize(pad("Start at"), "gray")} ${colorize(timeString, "cyan")}`);
|
|
68
60
|
console.log(` ${colorize(pad("Duration"), "gray")} ${colorize(`${duration}ms`, "cyan")} ${colorize(colorize(`(${ruleCount} ${this.pluralize(ruleCount, "rule")})`, "gray"), "dim")}`);
|
|
69
61
|
}
|
|
70
|
-
// Success message for all files clean
|
|
71
62
|
if (filesWithOffenses === 0 && files.length > 1) {
|
|
72
63
|
console.log("");
|
|
73
64
|
console.log(` ${colorize("✓", "brightGreen")} ${colorize("All files are clean!", "green")}`);
|
|
@@ -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,iBAAiB,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,IAAI,CAAA;QAElH,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACjB,OAAO,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE,CAAC,CAAA;QAE/C,
|
|
1
|
+
{"version":3,"file":"summary-reporter.js","sourceRoot":"","sources":["../../../src/cli/summary-reporter.ts"],"names":[],"mappings":"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"}
|
package/dist/src/cli.js
CHANGED
|
@@ -1,12 +1,50 @@
|
|
|
1
1
|
import { glob } from "glob";
|
|
2
2
|
import { Herb } from "@herb-tools/node-wasm";
|
|
3
|
+
import { existsSync, statSync } from "fs";
|
|
4
|
+
import { dirname, resolve, relative } from "path";
|
|
3
5
|
import { ArgumentParser } from "./cli/argument-parser.js";
|
|
4
6
|
import { FileProcessor } from "./cli/file-processor.js";
|
|
5
7
|
import { OutputManager } from "./cli/output-manager.js";
|
|
8
|
+
export * from "./cli/index.js";
|
|
6
9
|
export class CLI {
|
|
7
10
|
argumentParser = new ArgumentParser();
|
|
8
11
|
fileProcessor = new FileProcessor();
|
|
9
12
|
outputManager = new OutputManager();
|
|
13
|
+
projectPath = process.cwd();
|
|
14
|
+
getProjectPath() {
|
|
15
|
+
return this.projectPath;
|
|
16
|
+
}
|
|
17
|
+
findProjectRoot(startPath) {
|
|
18
|
+
let currentPath = resolve(startPath);
|
|
19
|
+
if (existsSync(currentPath) && statSync(currentPath).isFile()) {
|
|
20
|
+
currentPath = dirname(currentPath);
|
|
21
|
+
}
|
|
22
|
+
const projectIndicators = [
|
|
23
|
+
'package.json',
|
|
24
|
+
'Gemfile',
|
|
25
|
+
'.git',
|
|
26
|
+
'tsconfig.json',
|
|
27
|
+
'composer.json',
|
|
28
|
+
'pyproject.toml',
|
|
29
|
+
'requirements.txt',
|
|
30
|
+
'.herb.yml'
|
|
31
|
+
];
|
|
32
|
+
while (currentPath !== '/') {
|
|
33
|
+
for (const indicator of projectIndicators) {
|
|
34
|
+
if (existsSync(resolve(currentPath, indicator))) {
|
|
35
|
+
return currentPath;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const parentPath = dirname(currentPath);
|
|
39
|
+
if (parentPath === currentPath) {
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
currentPath = parentPath;
|
|
43
|
+
}
|
|
44
|
+
return existsSync(startPath) && statSync(startPath).isDirectory()
|
|
45
|
+
? startPath
|
|
46
|
+
: dirname(startPath);
|
|
47
|
+
}
|
|
10
48
|
exitWithError(message, formatOption, exitCode = 1) {
|
|
11
49
|
this.outputManager.outputError(message, {
|
|
12
50
|
formatOption,
|
|
@@ -14,6 +52,7 @@ export class CLI {
|
|
|
14
52
|
wrapLines: false,
|
|
15
53
|
truncateLines: false,
|
|
16
54
|
showTiming: false,
|
|
55
|
+
useGitHubActions: false,
|
|
17
56
|
startTime: 0,
|
|
18
57
|
startDate: new Date()
|
|
19
58
|
});
|
|
@@ -26,33 +65,78 @@ export class CLI {
|
|
|
26
65
|
wrapLines: false,
|
|
27
66
|
truncateLines: false,
|
|
28
67
|
showTiming: timingData?.showTiming ?? false,
|
|
68
|
+
useGitHubActions: false,
|
|
29
69
|
startTime: timingData?.startTime ?? Date.now(),
|
|
30
70
|
startDate: timingData?.startDate ?? new Date()
|
|
31
71
|
};
|
|
32
72
|
this.outputManager.outputInfo(message, outputOptions);
|
|
33
73
|
process.exit(exitCode);
|
|
34
74
|
}
|
|
75
|
+
determineProjectPath(pattern) {
|
|
76
|
+
if (pattern) {
|
|
77
|
+
const resolvedPattern = resolve(pattern);
|
|
78
|
+
if (existsSync(resolvedPattern)) {
|
|
79
|
+
const stats = statSync(resolvedPattern);
|
|
80
|
+
if (stats.isDirectory()) {
|
|
81
|
+
this.projectPath = resolvedPattern;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
this.projectPath = this.findProjectRoot(resolvedPattern);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
adjustPattern(pattern) {
|
|
90
|
+
if (!pattern) {
|
|
91
|
+
return '**/*.html.erb';
|
|
92
|
+
}
|
|
93
|
+
const resolvedPattern = resolve(pattern);
|
|
94
|
+
if (existsSync(resolvedPattern)) {
|
|
95
|
+
const stats = statSync(resolvedPattern);
|
|
96
|
+
if (stats.isDirectory()) {
|
|
97
|
+
return '**/*.html.erb';
|
|
98
|
+
}
|
|
99
|
+
else if (stats.isFile()) {
|
|
100
|
+
return relative(this.projectPath, resolvedPattern);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return pattern;
|
|
104
|
+
}
|
|
105
|
+
async beforeProcess() {
|
|
106
|
+
await Herb.load();
|
|
107
|
+
}
|
|
108
|
+
async afterProcess(_results, _outputOptions) {
|
|
109
|
+
// Hook for subclasses to add custom output after processing
|
|
110
|
+
}
|
|
35
111
|
async run() {
|
|
36
112
|
const startTime = Date.now();
|
|
37
113
|
const startDate = new Date();
|
|
38
|
-
|
|
114
|
+
let { pattern, formatOption, showTiming, theme, wrapLines, truncateLines, useGitHubActions } = this.argumentParser.parse(process.argv);
|
|
115
|
+
this.determineProjectPath(pattern);
|
|
116
|
+
pattern = this.adjustPattern(pattern);
|
|
39
117
|
const outputOptions = {
|
|
40
118
|
formatOption,
|
|
41
119
|
theme,
|
|
42
120
|
wrapLines,
|
|
43
121
|
truncateLines,
|
|
44
122
|
showTiming,
|
|
123
|
+
useGitHubActions,
|
|
45
124
|
startTime,
|
|
46
125
|
startDate
|
|
47
126
|
};
|
|
48
127
|
try {
|
|
49
|
-
await
|
|
50
|
-
const files = await glob(pattern);
|
|
128
|
+
await this.beforeProcess();
|
|
129
|
+
const files = await glob(pattern, { cwd: this.projectPath });
|
|
51
130
|
if (files.length === 0) {
|
|
52
131
|
this.exitWithInfo(`No files found matching pattern: ${pattern}`, formatOption, 0, { startTime, startDate, showTiming });
|
|
53
132
|
}
|
|
54
|
-
const
|
|
133
|
+
const context = {
|
|
134
|
+
projectPath: this.projectPath,
|
|
135
|
+
pattern: pattern
|
|
136
|
+
};
|
|
137
|
+
const results = await this.fileProcessor.processFiles(files, formatOption, context);
|
|
55
138
|
await this.outputManager.outputResults({ ...results, files }, outputOptions);
|
|
139
|
+
await this.afterProcess(results, outputOptions);
|
|
56
140
|
if (results.totalErrors > 0) {
|
|
57
141
|
process.exit(1);
|
|
58
142
|
}
|