1/** 2 * @fileoverview "table reporter. 3 * @author Gajus Kuizinas <gajus@gajus.com> 4 */ 5"use strict"; 6 7//------------------------------------------------------------------------------ 8// Requirements 9//------------------------------------------------------------------------------ 10 11const chalk = require("chalk"), 12 table = require("table").table; 13 14//------------------------------------------------------------------------------ 15// Helpers 16//------------------------------------------------------------------------------ 17 18/** 19 * Given a word and a count, append an "s" if count is not one. 20 * @param {string} word A word. 21 * @param {number} count Quantity. 22 * @returns {string} The original word with an s on the end if count is not one. 23 */ 24function pluralize(word, count) { 25 return (count === 1 ? word : `${word}s`); 26} 27 28/** 29 * Draws text table. 30 * @param {Array<Object>} messages Error messages relating to a specific file. 31 * @returns {string} A text table. 32 */ 33function drawTable(messages) { 34 const rows = []; 35 36 if (messages.length === 0) { 37 return ""; 38 } 39 40 rows.push([ 41 chalk.bold("Line"), 42 chalk.bold("Column"), 43 chalk.bold("Type"), 44 chalk.bold("Message"), 45 chalk.bold("Rule ID") 46 ]); 47 48 messages.forEach(message => { 49 let messageType; 50 51 if (message.fatal || message.severity === 2) { 52 messageType = chalk.red("error"); 53 } else { 54 messageType = chalk.yellow("warning"); 55 } 56 57 rows.push([ 58 message.line || 0, 59 message.column || 0, 60 messageType, 61 message.message, 62 message.ruleId || "" 63 ]); 64 }); 65 66 return table(rows, { 67 columns: { 68 0: { 69 width: 8, 70 wrapWord: true 71 }, 72 1: { 73 width: 8, 74 wrapWord: true 75 }, 76 2: { 77 width: 8, 78 wrapWord: true 79 }, 80 3: { 81 paddingRight: 5, 82 width: 50, 83 wrapWord: true 84 }, 85 4: { 86 width: 20, 87 wrapWord: true 88 } 89 }, 90 drawHorizontalLine(index) { 91 return index === 1; 92 } 93 }); 94} 95 96/** 97 * Draws a report (multiple tables). 98 * @param {Array} results Report results for every file. 99 * @returns {string} A column of text tables. 100 */ 101function drawReport(results) { 102 let files; 103 104 files = results.map(result => { 105 if (!result.messages.length) { 106 return ""; 107 } 108 109 return `\n${result.filePath}\n\n${drawTable(result.messages)}`; 110 }); 111 112 files = files.filter(content => content.trim()); 113 114 return files.join(""); 115} 116 117//------------------------------------------------------------------------------ 118// Public Interface 119//------------------------------------------------------------------------------ 120 121module.exports = function(report) { 122 let result, 123 errorCount, 124 warningCount; 125 126 result = ""; 127 errorCount = 0; 128 warningCount = 0; 129 130 report.forEach(fileReport => { 131 errorCount += fileReport.errorCount; 132 warningCount += fileReport.warningCount; 133 }); 134 135 if (errorCount || warningCount) { 136 result = drawReport(report); 137 } 138 139 result += `\n${table([ 140 [ 141 chalk.red(pluralize(`${errorCount} Error`, errorCount)) 142 ], 143 [ 144 chalk.yellow(pluralize(`${warningCount} Warning`, warningCount)) 145 ] 146 ], { 147 columns: { 148 0: { 149 width: 110, 150 wrapWord: true 151 } 152 }, 153 drawHorizontalLine() { 154 return true; 155 } 156 })}`; 157 158 return result; 159}; 160