Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update: Add ESLint API (refs eslint/rfcs#40) #12939

Merged
merged 73 commits into from Apr 24, 2020
Merged
Show file tree
Hide file tree
Changes from 61 commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
df75389
Update: Add ESLint API
kaicataldo Feb 7, 2020
eb5b486
Refactor
kaicataldo Feb 18, 2020
f3137ba
Address feedback
kaicataldo Feb 19, 2020
09fbeaa
Make CLIEngine instance a private property
kaicataldo Feb 19, 2020
75655f8
Validate plugin objects
kaicataldo Feb 19, 2020
d5f79e3
Add test clarifying CLIEngine extensions behavior
kaicataldo Feb 19, 2020
00b2bb0
Add lintText() tests
kaicataldo Feb 26, 2020
b93a625
Add lintFiles() tests
kaicataldo Mar 6, 2020
c2c7c56
Merge branch 'master' into eslint-api
mysticatea Apr 12, 2020
c6bee0a
update usedDeprecatedRules property
mysticatea Apr 12, 2020
c786ca7
update around loadFormatter
mysticatea Apr 12, 2020
fc1e723
fix usedDeprecatedRules
mysticatea Apr 12, 2020
8bcdac2
fix a bug about addPlugin method
mysticatea Apr 12, 2020
6105ea2
improve validation
mysticatea Apr 12, 2020
6a3fb16
change constructor options
mysticatea Apr 12, 2020
545b360
add errorOnUnmatchedPattern and etc
mysticatea Apr 13, 2020
7e04698
update bin/eslint.js and cli.js to use ESLint class
mysticatea Apr 13, 2020
5427043
rewrite tests
mysticatea Apr 15, 2020
54e6fa9
fix tests
mysticatea Apr 15, 2020
e5aea0a
remove compareResultsByFilePath
mysticatea Apr 15, 2020
ac17cec
fix tests
mysticatea Apr 15, 2020
49f302f
fix tests
mysticatea Apr 15, 2020
8421fb3
remove deprecated source property
mysticatea Apr 18, 2020
8322e01
expose the new ESLint class
mysticatea Apr 18, 2020
dbc286c
update nodejs-api.md
mysticatea Apr 18, 2020
4b7a220
fix links
mysticatea Apr 18, 2020
72c42d0
fix links
mysticatea Apr 18, 2020
499b8d7
Revert "remove deprecated source property"
mysticatea Apr 20, 2020
35889b9
add author
mysticatea Apr 20, 2020
2131de5
fix typo
mysticatea Apr 20, 2020
630c65e
add `LintResult#source` to docs
mysticatea Apr 20, 2020
8e9f961
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 22, 2020
29262c8
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 22, 2020
73a3d39
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 22, 2020
47d18d3
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 22, 2020
844bc8d
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 22, 2020
ce0b4be
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 22, 2020
e2d79e5
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 22, 2020
8f44116
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 22, 2020
78a1989
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 22, 2020
72d3237
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 22, 2020
bb89cde
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 22, 2020
eec219e
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 22, 2020
3a3e00c
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 22, 2020
046b66a
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 22, 2020
818438b
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 22, 2020
eff35d4
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 22, 2020
c6d66a8
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 22, 2020
f0aeafb
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 22, 2020
7b445ca
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 22, 2020
da252e6
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 22, 2020
db8600f
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 22, 2020
f244a04
Update lib/eslint/eslint.js
mysticatea Apr 22, 2020
fc91aea
Update lib/eslint/eslint.js
mysticatea Apr 22, 2020
9daca9d
Update tests/lib/cli.js
mysticatea Apr 22, 2020
186eebd
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 23, 2020
13d1de7
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 23, 2020
d2cb761
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 23, 2020
00399d2
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 23, 2020
b83ee7f
add loadFormatter description
mysticatea Apr 23, 2020
6c047f2
add about <text>
mysticatea Apr 23, 2020
d91fa56
fix error message
mysticatea Apr 23, 2020
21c2300
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 24, 2020
fdabe84
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 24, 2020
8e315cd
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 24, 2020
e1a94a4
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 24, 2020
d43d12c
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 24, 2020
ac957d2
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 24, 2020
de9e71b
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 24, 2020
98d483d
Update docs/developer-guide/nodejs-api.md
mysticatea Apr 24, 2020
20dc74d
Update lib/cli-engine/cli-engine.js
mysticatea Apr 24, 2020
27cc934
Update tests/lib/cli.js
mysticatea Apr 24, 2020
97c0b19
Merge branch 'master' into eslint-api
mysticatea Apr 24, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
192 changes: 115 additions & 77 deletions bin/eslint.js
Expand Up @@ -12,97 +12,135 @@
// to use V8's code cache to speed up instantiation time
require("v8-compile-cache");

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------

const useStdIn = process.argv.includes("--stdin"),
init = process.argv.includes("--init"),
debug = process.argv.includes("--debug");

// must do this initialization *before* other requires in order to work
if (debug) {
if (process.argv.includes("--debug")) {
require("debug").enable("eslint:*,-eslint:code-path");
}

//------------------------------------------------------------------------------
// Requirements
// Helpers
//------------------------------------------------------------------------------

// now we can safely include the other modules that use debug
const path = require("path"),
fs = require("fs"),
cli = require("../lib/cli");

//------------------------------------------------------------------------------
// Execution
//------------------------------------------------------------------------------
/**
* Read data from stdin til the end.
*
* Note: See
* - https://github.com/nodejs/node/blob/master/doc/api/process.md#processstdin
* - https://github.com/nodejs/node/blob/master/doc/api/process.md#a-note-on-process-io
* - https://lists.gnu.org/archive/html/bug-gnu-emacs/2016-01/msg00419.html
* - https://github.com/nodejs/node/issues/7439 (historical)
*
* On Windows using `fs.readFileSync(STDIN_FILE_DESCRIPTOR, "utf8")` seems
* to read 4096 bytes before blocking and never drains to read further data.
*
* The investigation on the Emacs thread indicates:
*
* > Emacs on MS-Windows uses pipes to communicate with subprocesses; a
* > pipe on Windows has a 4K buffer. So as soon as Emacs writes more than
* > 4096 bytes to the pipe, the pipe becomes full, and Emacs then waits for
* > the subprocess to read its end of the pipe, at which time Emacs will
* > write the rest of the stuff.
* @returns {Promise<string>} The read text.
*/
function readStdin() {
return new Promise((resolve, reject) => {
let content = "";
let chunk = "";

process.stdin
.setEncoding("utf8")
.on("readable", () => {
while ((chunk = process.stdin.read()) !== null) {
content += chunk;
}
})
.on("end", () => resolve(content))
.on("error", reject);
});
}

process.once("uncaughtException", err => {
/**
* Get the error message of a given value.
* @param {any} error The value to get.
* @returns {string} The error message.
*/
function getErrorMessage(error) {

// lazy load
// Lazy loading because those are used only if error happened.
const fs = require("fs");
const path = require("path");
const util = require("util");
const lodash = require("lodash");

if (typeof err.messageTemplate === "string" && err.messageTemplate.length > 0) {
const template = lodash.template(fs.readFileSync(path.resolve(__dirname, `../messages/${err.messageTemplate}.txt`), "utf-8"));
const pkg = require("../package.json");
// Foolproof -- thirdparty module might throw non-object.
if (typeof error !== "object" || error === null) {
return String(error);
}

// Use templates if `error.messageTemplate` is present.
if (typeof error.messageTemplate === "string") {
try {
const templateFilePath = path.resolve(
__dirname,
`../messages/${error.messageTemplate}.txt`
);

// Use sync API because Node.js should exit at this tick.
const templateText = fs.readFileSync(templateFilePath, "utf-8");
const template = lodash.template(templateText);

return template(error.messageData || {});
} catch {

// Ignore template error then fallback to use `error.stack`.
}
}

console.error("\nOops! Something went wrong! :(");
console.error(`\nESLint: ${pkg.version}.\n\n${template(err.messageData || {})}`);
} else {
console.error(err.stack);
// Use the stacktrace if it's an error object.
if (typeof error.stack === "string") {
return error.stack;
}

// Otherwise, dump the object.
return util.format("%o", error);
}

/**
* Catch and report unexpected error.
* @param {any} error The thrown error object.
* @returns {void}
*/
function onFatalError(error) {
process.exitCode = 2;
});

if (useStdIn) {

/*
* Note: See
* - https://github.com/nodejs/node/blob/master/doc/api/process.md#processstdin
* - https://github.com/nodejs/node/blob/master/doc/api/process.md#a-note-on-process-io
* - https://lists.gnu.org/archive/html/bug-gnu-emacs/2016-01/msg00419.html
* - https://github.com/nodejs/node/issues/7439 (historical)
*
* On Windows using `fs.readFileSync(STDIN_FILE_DESCRIPTOR, "utf8")` seems
* to read 4096 bytes before blocking and never drains to read further data.
*
* The investigation on the Emacs thread indicates:
*
* > Emacs on MS-Windows uses pipes to communicate with subprocesses; a
* > pipe on Windows has a 4K buffer. So as soon as Emacs writes more than
* > 4096 bytes to the pipe, the pipe becomes full, and Emacs then waits for
* > the subprocess to read its end of the pipe, at which time Emacs will
* > write the rest of the stuff.
*
* Using the nodejs code example for reading from stdin.
*/
let contents = "",
chunk = "";

process.stdin.setEncoding("utf8");
process.stdin.on("readable", () => {

// Use a loop to make sure we read all available data.
while ((chunk = process.stdin.read()) !== null) {
contents += chunk;
}
});

process.stdin.on("end", () => {
process.exitCode = cli.execute(process.argv, contents, "utf8");
});
} else if (init) {
const configInit = require("../lib/init/config-initializer");

configInit.initializeConfig().then(() => {
process.exitCode = 0;
}).catch(err => {
process.exitCode = 1;
console.error(err.message);
console.error(err.stack);
});
} else {
process.exitCode = cli.execute(process.argv);
const { version } = require("../package.json");
const message = getErrorMessage(error);

console.error(`
Oops! Something went wrong! :(
ESLint: ${version}
${message}`);
}

//------------------------------------------------------------------------------
// Execution
//------------------------------------------------------------------------------

(async function main() {
process.on("uncaughtException", onFatalError);
process.on("unhandledRejection", onFatalError);

// Call the config initializer if `--init` is present.
if (process.argv.includes("--init")) {
await require("../lib/init/config-initializer").initializeConfig();
return;
}

// Otherwise, call the CLI.
process.exitCode = await require("../lib/cli").execute(
process.argv,
process.argv.includes("--stdin") ? await readStdin() : null
);
}()).catch(onFatalError);