1 |
|
2 |
|
3 |
|
4 |
|
5 | "use strict";
|
6 |
|
7 | const chalk = require("chalk");
|
8 | const { codeFrameColumns } = require("@babel/code-frame");
|
9 | const path = require("path");
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 | function pluralize(word, count) {
|
22 | return (count === 1 ? word : `${word}s`);
|
23 | }
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 | function formatFilePath(filePath, line, column) {
|
33 | let relPath = path.relative(process.cwd(), filePath);
|
34 |
|
35 | if (line && column) {
|
36 | relPath += `:${line}:${column}`;
|
37 | }
|
38 |
|
39 | return chalk.green(relPath);
|
40 | }
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 | function formatMessage(message, parentResult) {
|
49 | const type = (message.fatal || message.severity === 2) ? chalk.red("error") : chalk.yellow("warning");
|
50 | const msg = `${chalk.bold(message.message.replace(/([^ ])\.$/u, "$1"))}`;
|
51 | const ruleId = message.fatal ? "" : chalk.dim(`(${message.ruleId})`);
|
52 | const filePath = formatFilePath(parentResult.filePath, message.line, message.column);
|
53 | const sourceCode = parentResult.output ? parentResult.output : parentResult.source;
|
54 |
|
55 | const firstLine = [
|
56 | `${type}:`,
|
57 | `${msg}`,
|
58 | ruleId ? `${ruleId}` : "",
|
59 | sourceCode ? `at ${filePath}:` : `at ${filePath}`
|
60 | ].filter(String).join(" ");
|
61 |
|
62 | const result = [firstLine];
|
63 |
|
64 | if (sourceCode) {
|
65 | result.push(
|
66 | codeFrameColumns(sourceCode, { start: { line: message.line, column: message.column } }, { highlightCode: false })
|
67 | );
|
68 | }
|
69 |
|
70 | return result.join("\n");
|
71 | }
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 |
|
79 |
|
80 |
|
81 | function formatSummary(errors, warnings, fixableErrors, fixableWarnings) {
|
82 | const summaryColor = errors > 0 ? "red" : "yellow";
|
83 | const summary = [];
|
84 | const fixablesSummary = [];
|
85 |
|
86 | if (errors > 0) {
|
87 | summary.push(`${errors} ${pluralize("error", errors)}`);
|
88 | }
|
89 |
|
90 | if (warnings > 0) {
|
91 | summary.push(`${warnings} ${pluralize("warning", warnings)}`);
|
92 | }
|
93 |
|
94 | if (fixableErrors > 0) {
|
95 | fixablesSummary.push(`${fixableErrors} ${pluralize("error", fixableErrors)}`);
|
96 | }
|
97 |
|
98 | if (fixableWarnings > 0) {
|
99 | fixablesSummary.push(`${fixableWarnings} ${pluralize("warning", fixableWarnings)}`);
|
100 | }
|
101 |
|
102 | let output = chalk[summaryColor].bold(`${summary.join(" and ")} found.`);
|
103 |
|
104 | if (fixableErrors || fixableWarnings) {
|
105 | output += chalk[summaryColor].bold(`\n${fixablesSummary.join(" and ")} potentially fixable with the \`--fix\` option.`);
|
106 | }
|
107 |
|
108 | return output;
|
109 | }
|
110 |
|
111 |
|
112 |
|
113 |
|
114 |
|
115 | module.exports = function(results) {
|
116 | let errors = 0;
|
117 | let warnings = 0;
|
118 | let fixableErrors = 0;
|
119 | let fixableWarnings = 0;
|
120 |
|
121 | const resultsWithMessages = results.filter(result => result.messages.length > 0);
|
122 |
|
123 | let output = resultsWithMessages.reduce((resultsOutput, result) => {
|
124 | const messages = result.messages.map(message => `${formatMessage(message, result)}\n\n`);
|
125 |
|
126 | errors += result.errorCount;
|
127 | warnings += result.warningCount;
|
128 | fixableErrors += result.fixableErrorCount;
|
129 | fixableWarnings += result.fixableWarningCount;
|
130 |
|
131 | return resultsOutput.concat(messages);
|
132 | }, []).join("\n");
|
133 |
|
134 | output += "\n";
|
135 | output += formatSummary(errors, warnings, fixableErrors, fixableWarnings);
|
136 |
|
137 | return (errors + warnings) > 0 ? output : "";
|
138 | };
|