| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 | /** * @fileoverview Codeframe reporter * @author Vitor Balocco */"use strict";const chalk = require("chalk");const codeFrame = 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(/([^ ])\.$/, "$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(            codeFrame(sourceCode, message.line, 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 : "";};
 |