You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
3.7 KiB

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