eslint.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #!/usr/bin/env node
  2. /**
  3. * @fileoverview Main CLI that is run via the eslint command.
  4. * @author Nicholas C. Zakas
  5. */
  6. /* eslint no-console:off */
  7. "use strict";
  8. // to use V8's code cache to speed up instantiation time
  9. require("v8-compile-cache");
  10. //------------------------------------------------------------------------------
  11. // Helpers
  12. //------------------------------------------------------------------------------
  13. const useStdIn = process.argv.includes("--stdin"),
  14. init = process.argv.includes("--init"),
  15. debug = process.argv.includes("--debug");
  16. // must do this initialization *before* other requires in order to work
  17. if (debug) {
  18. require("debug").enable("eslint:*,-eslint:code-path");
  19. }
  20. //------------------------------------------------------------------------------
  21. // Requirements
  22. //------------------------------------------------------------------------------
  23. // now we can safely include the other modules that use debug
  24. const path = require("path"),
  25. fs = require("fs"),
  26. cli = require("../lib/cli");
  27. //------------------------------------------------------------------------------
  28. // Execution
  29. //------------------------------------------------------------------------------
  30. process.once("uncaughtException", err => {
  31. // lazy load
  32. const lodash = require("lodash");
  33. if (typeof err.messageTemplate === "string" && err.messageTemplate.length > 0) {
  34. const template = lodash.template(fs.readFileSync(path.resolve(__dirname, `../messages/${err.messageTemplate}.txt`), "utf-8"));
  35. const pkg = require("../package.json");
  36. console.error("\nOops! Something went wrong! :(");
  37. console.error(`\nESLint: ${pkg.version}.\n\n${template(err.messageData || {})}`);
  38. } else {
  39. console.error(err.stack);
  40. }
  41. process.exitCode = 2;
  42. });
  43. if (useStdIn) {
  44. /*
  45. * Note: See
  46. * - https://github.com/nodejs/node/blob/master/doc/api/process.md#processstdin
  47. * - https://github.com/nodejs/node/blob/master/doc/api/process.md#a-note-on-process-io
  48. * - https://lists.gnu.org/archive/html/bug-gnu-emacs/2016-01/msg00419.html
  49. * - https://github.com/nodejs/node/issues/7439 (historical)
  50. *
  51. * On Windows using `fs.readFileSync(STDIN_FILE_DESCRIPTOR, "utf8")` seems
  52. * to read 4096 bytes before blocking and never drains to read further data.
  53. *
  54. * The investigation on the Emacs thread indicates:
  55. *
  56. * > Emacs on MS-Windows uses pipes to communicate with subprocesses; a
  57. * > pipe on Windows has a 4K buffer. So as soon as Emacs writes more than
  58. * > 4096 bytes to the pipe, the pipe becomes full, and Emacs then waits for
  59. * > the subprocess to read its end of the pipe, at which time Emacs will
  60. * > write the rest of the stuff.
  61. *
  62. * Using the nodejs code example for reading from stdin.
  63. */
  64. let contents = "",
  65. chunk = "";
  66. process.stdin.setEncoding("utf8");
  67. process.stdin.on("readable", () => {
  68. // Use a loop to make sure we read all available data.
  69. while ((chunk = process.stdin.read()) !== null) {
  70. contents += chunk;
  71. }
  72. });
  73. process.stdin.on("end", () => {
  74. process.exitCode = cli.execute(process.argv, contents, "utf8");
  75. });
  76. } else if (init) {
  77. const configInit = require("../lib/init/config-initializer");
  78. configInit.initializeConfig().then(() => {
  79. process.exitCode = 0;
  80. }).catch(err => {
  81. process.exitCode = 1;
  82. console.error(err.message);
  83. console.error(err.stack);
  84. });
  85. } else {
  86. process.exitCode = cli.execute(process.argv);
  87. }