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