123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- /**
- * @fileoverview Codeframe reporter
- * @author Vitor Balocco
- */
- "use strict";
- const chalk = require("chalk");
- const { codeFrameColumns } = require("@babel/code-frame");
- const path = require("path");
- //------------------------------------------------------------------------------
- // Helpers
- //------------------------------------------------------------------------------
- /**
- * Given a word and a count, append an s if count is not one.
- * @param {string} word A word in its singular form.
- * @param {number} count A number controlling whether word should be pluralized.
- * @returns {string} The original word with an s on the end if count is not one.
- */
- function pluralize(word, count) {
- return (count === 1 ? word : `${word}s`);
- }
- /**
- * Gets a formatted relative file path from an absolute path and a line/column in the file.
- * @param {string} filePath The absolute file path to format.
- * @param {number} line The line from the file to use for formatting.
- * @param {number} column The column from the file to use for formatting.
- * @returns {string} The formatted file path.
- */
- function formatFilePath(filePath, line, column) {
- let relPath = path.relative(process.cwd(), filePath);
- if (line && column) {
- relPath += `:${line}:${column}`;
- }
- return chalk.green(relPath);
- }
- /**
- * Gets the formatted output for a given message.
- * @param {Object} message The object that represents this message.
- * @param {Object} parentResult The result object that this message belongs to.
- * @returns {string} The formatted output.
- */
- function formatMessage(message, parentResult) {
- const type = (message.fatal || message.severity === 2) ? chalk.red("error") : chalk.yellow("warning");
- const msg = `${chalk.bold(message.message.replace(/([^ ])\.$/u, "$1"))}`;
- const ruleId = message.fatal ? "" : chalk.dim(`(${message.ruleId})`);
- const filePath = formatFilePath(parentResult.filePath, message.line, message.column);
- const sourceCode = parentResult.output ? parentResult.output : parentResult.source;
- const firstLine = [
- `${type}:`,
- `${msg}`,
- ruleId ? `${ruleId}` : "",
- sourceCode ? `at ${filePath}:` : `at ${filePath}`
- ].filter(String).join(" ");
- const result = [firstLine];
- if (sourceCode) {
- result.push(
- codeFrameColumns(sourceCode, { start: { line: message.line, column: message.column } }, { highlightCode: false })
- );
- }
- return result.join("\n");
- }
- /**
- * Gets the formatted output summary for a given number of errors and warnings.
- * @param {number} errors The number of errors.
- * @param {number} warnings The number of warnings.
- * @param {number} fixableErrors The number of fixable errors.
- * @param {number} fixableWarnings The number of fixable warnings.
- * @returns {string} The formatted output summary.
- */
- function formatSummary(errors, warnings, fixableErrors, fixableWarnings) {
- const summaryColor = errors > 0 ? "red" : "yellow";
- const summary = [];
- const fixablesSummary = [];
- if (errors > 0) {
- summary.push(`${errors} ${pluralize("error", errors)}`);
- }
- if (warnings > 0) {
- summary.push(`${warnings} ${pluralize("warning", warnings)}`);
- }
- if (fixableErrors > 0) {
- fixablesSummary.push(`${fixableErrors} ${pluralize("error", fixableErrors)}`);
- }
- if (fixableWarnings > 0) {
- fixablesSummary.push(`${fixableWarnings} ${pluralize("warning", fixableWarnings)}`);
- }
- let output = chalk[summaryColor].bold(`${summary.join(" and ")} found.`);
- if (fixableErrors || fixableWarnings) {
- output += chalk[summaryColor].bold(`\n${fixablesSummary.join(" and ")} potentially fixable with the \`--fix\` option.`);
- }
- return output;
- }
- //------------------------------------------------------------------------------
- // Public Interface
- //------------------------------------------------------------------------------
- module.exports = function(results) {
- let errors = 0;
- let warnings = 0;
- let fixableErrors = 0;
- let fixableWarnings = 0;
- const resultsWithMessages = results.filter(result => result.messages.length > 0);
- let output = resultsWithMessages.reduce((resultsOutput, result) => {
- const messages = result.messages.map(message => `${formatMessage(message, result)}\n\n`);
- errors += result.errorCount;
- warnings += result.warningCount;
- fixableErrors += result.fixableErrorCount;
- fixableWarnings += result.fixableWarningCount;
- return resultsOutput.concat(messages);
- }, []).join("\n");
- output += "\n";
- output += formatSummary(errors, warnings, fixableErrors, fixableWarnings);
- return (errors + warnings) > 0 ? output : "";
- };
|