stylish.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /**
  2. * @fileoverview Stylish reporter
  3. * @author Sindre Sorhus
  4. */
  5. "use strict";
  6. const chalk = require("chalk"),
  7. stripAnsi = require("strip-ansi"),
  8. table = require("text-table");
  9. //------------------------------------------------------------------------------
  10. // Helpers
  11. //------------------------------------------------------------------------------
  12. /**
  13. * Given a word and a count, append an s if count is not one.
  14. * @param {string} word A word in its singular form.
  15. * @param {int} count A number controlling whether word should be pluralized.
  16. * @returns {string} The original word with an s on the end if count is not one.
  17. */
  18. function pluralize(word, count) {
  19. return (count === 1 ? word : `${word}s`);
  20. }
  21. //------------------------------------------------------------------------------
  22. // Public Interface
  23. //------------------------------------------------------------------------------
  24. module.exports = function(results) {
  25. let output = "\n",
  26. errorCount = 0,
  27. warningCount = 0,
  28. fixableErrorCount = 0,
  29. fixableWarningCount = 0,
  30. summaryColor = "yellow";
  31. results.forEach(result => {
  32. const messages = result.messages;
  33. if (messages.length === 0) {
  34. return;
  35. }
  36. errorCount += result.errorCount;
  37. warningCount += result.warningCount;
  38. fixableErrorCount += result.fixableErrorCount;
  39. fixableWarningCount += result.fixableWarningCount;
  40. output += `${chalk.underline(result.filePath)}\n`;
  41. output += `${table(
  42. messages.map(message => {
  43. let messageType;
  44. if (message.fatal || message.severity === 2) {
  45. messageType = chalk.red("error");
  46. summaryColor = "red";
  47. } else {
  48. messageType = chalk.yellow("warning");
  49. }
  50. return [
  51. "",
  52. message.line || 0,
  53. message.column || 0,
  54. messageType,
  55. message.message.replace(/([^ ])\.$/u, "$1"),
  56. chalk.dim(message.ruleId || "")
  57. ];
  58. }),
  59. {
  60. align: ["", "r", "l"],
  61. stringLength(str) {
  62. return stripAnsi(str).length;
  63. }
  64. }
  65. ).split("\n").map(el => el.replace(/(\d+)\s+(\d+)/u, (m, p1, p2) => chalk.dim(`${p1}:${p2}`))).join("\n")}\n\n`;
  66. });
  67. const total = errorCount + warningCount;
  68. if (total > 0) {
  69. output += chalk[summaryColor].bold([
  70. "\u2716 ", total, pluralize(" problem", total),
  71. " (", errorCount, pluralize(" error", errorCount), ", ",
  72. warningCount, pluralize(" warning", warningCount), ")\n"
  73. ].join(""));
  74. if (fixableErrorCount > 0 || fixableWarningCount > 0) {
  75. output += chalk[summaryColor].bold([
  76. " ", fixableErrorCount, pluralize(" error", fixableErrorCount), " and ",
  77. fixableWarningCount, pluralize(" warning", fixableWarningCount),
  78. " potentially fixable with the `--fix` option.\n"
  79. ].join(""));
  80. }
  81. }
  82. // Resets output color, for prevent change on top level
  83. return total > 0 ? chalk.reset(output) : "";
  84. };