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

tools: update to ESLint 4.3.0 #14417

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions .eslintrc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,17 +102,17 @@ rules:
func-name-matching: error
func-style: [error, declaration, {allowArrowFunctions: true}]
# indent: [error, 2, {ArrayExpression: first,
# CallExpression: {arguments: first},
# FunctionDeclaration: {parameters: first},
# FunctionExpression: {parameters: first},
# MemberExpression: off,
# ObjectExpression: first,
# SwitchCase: 1}]
# CallExpression: {arguments: first},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will conflict with #14403.
IMHO both seem appropriate for this change...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No conflict with git am -3 because they're both the exact same change. :-D

# FunctionDeclaration: {parameters: first},
# FunctionExpression: {parameters: first},
# MemberExpression: off,
# ObjectExpression: first,
# SwitchCase: 1}]
indent-legacy: [error, 2, {ArrayExpression: first,
CallExpression: {arguments: first},
MemberExpression: 1,
ObjectExpression: first,
SwitchCase: 1}]
CallExpression: {arguments: first},
MemberExpression: 1,
ObjectExpression: first,
SwitchCase: 1}]
key-spacing: [error, {mode: minimum}]
keyword-spacing: error
linebreak-style: [error, unix]
Expand Down
3 changes: 2 additions & 1 deletion lib/async_hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ var tmp_async_hook_fields = null;
// async execution. These are tracked so if the user didn't include callbacks
// for a given step, that step can bail out early.
const { kInit, kBefore, kAfter, kDestroy, kTotals, kCurrentAsyncId,
kCurrentTriggerId, kAsyncUidCntr, kInitTriggerId } = async_wrap.constants;
kCurrentTriggerId, kAsyncUidCntr,
kInitTriggerId } = async_wrap.constants;

const { async_id_symbol, trigger_id_symbol } = async_wrap;

Expand Down
2 changes: 1 addition & 1 deletion lib/child_process.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
const util = require('util');
const { deprecate, convertToValidSignal } = require('internal/util');
const { createPromise,
promiseResolve, promiseReject } = process.binding('util');
promiseResolve, promiseReject } = process.binding('util');
const debug = util.debuglog('child_process');

const uv = process.binding('uv');
Expand Down
7 changes: 3 additions & 4 deletions tools/eslint/bin/eslint.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,10 @@ process.once("uncaughtException", err => {
if (typeof err.messageTemplate === "string" && err.messageTemplate.length > 0) {
const template = lodash.template(fs.readFileSync(path.resolve(__dirname, `../messages/${err.messageTemplate}.txt`), "utf-8"));

console.log("\nOops! Something went wrong! :(");
console.log(`\n${template(err.messageData || {})}`);
console.error("\nOops! Something went wrong! :(");
console.error(`\n${template(err.messageData || {})}`);
} else {
console.log(err.message);
console.log(err.stack);
console.error(err.stack);
}

process.exitCode = 1;
Expand Down
137 changes: 123 additions & 14 deletions tools/eslint/lib/config/config-initializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
const util = require("util"),
inquirer = require("inquirer"),
ProgressBar = require("progress"),
semver = require("semver"),
autoconfig = require("./autoconfig.js"),
ConfigFile = require("./config-file"),
ConfigOps = require("./config-ops"),
getSourceCodeOfFiles = require("../util/source-code-util").getSourceCodeOfFiles,
ModuleResolver = require("../util/module-resolver"),
npmUtil = require("../util/npm-util"),
recConfig = require("../../conf/eslint-recommended"),
log = require("../logging");
Expand Down Expand Up @@ -56,12 +58,35 @@ function writeFile(config, format) {
}
}

/**
* Get the peer dependencies of the given module.
* This adds the gotten value to cache at the first time, then reuses it.
* In a process, this function is called twice, but `npmUtil.fetchPeerDependencies` needs to access network which is relatively slow.
* @param {string} moduleName The module name to get.
* @returns {Object} The peer dependencies of the given module.
* This object is the object of `peerDependencies` field of `package.json`.
*/
function getPeerDependencies(moduleName) {
let result = getPeerDependencies.cache.get(moduleName);

if (!result) {
log.info(`Checking peerDependencies of ${moduleName}`);

result = npmUtil.fetchPeerDependencies(moduleName);
getPeerDependencies.cache.set(moduleName, result);
}

return result;
}
getPeerDependencies.cache = new Map();

/**
* Synchronously install necessary plugins, configs, parsers, etc. based on the config
* @param {Object} config config object
* @param {boolean} [installESLint=true] If `false` is given, it does not install eslint.
* @returns {void}
*/
function installModules(config) {
function installModules(config, installESLint) {
const modules = {};

// Create a list of modules which should be installed based on config
Expand All @@ -73,11 +98,10 @@ function installModules(config) {
if (config.extends && config.extends.indexOf("eslint:") === -1) {
const moduleName = `eslint-config-${config.extends}`;

log.info(`Checking peerDependencies of ${moduleName}`);
modules[moduleName] = "latest";
Object.assign(
modules,
npmUtil.fetchPeerDependencies(`${moduleName}@latest`)
getPeerDependencies(`${moduleName}@latest`)
);
}

Expand All @@ -86,15 +110,17 @@ function installModules(config) {
return;
}

// Add eslint to list in case user does not have it installed locally
modules.eslint = modules.eslint || "latest";

// Mark to show messages if it's new installation of eslint.
const installStatus = npmUtil.checkDevDeps(["eslint"]);
if (installESLint === false) {
delete modules.eslint;
} else {
const installStatus = npmUtil.checkDevDeps(["eslint"]);

if (installStatus.eslint === false) {
log.info("Local ESLint installation not found.");
config.installedESLint = true;
// Mark to show messages if it's new installation of eslint.
if (installStatus.eslint === false) {
log.info("Local ESLint installation not found.");
modules.eslint = modules.eslint || "latest";
config.installedESLint = true;
}
}

// Install packages
Expand Down Expand Up @@ -265,9 +291,10 @@ function processAnswers(answers) {
/**
* process user's style guide of choice and return an appropriate config object.
* @param {string} guide name of the chosen style guide
* @param {boolean} [installESLint=true] If `false` is given, it does not install eslint.
* @returns {Object} config object
*/
function getConfigForStyleGuide(guide) {
function getConfigForStyleGuide(guide, installESLint) {
const guides = {
google: { extends: "google" },
airbnb: { extends: "airbnb" },
Expand All @@ -279,11 +306,74 @@ function getConfigForStyleGuide(guide) {
throw new Error("You referenced an unsupported guide.");
}

installModules(guides[guide]);
installModules(guides[guide], installESLint);

return guides[guide];
}

/**
* Get the version of the local ESLint.
* @returns {string|null} The version. If the local ESLint was not found, returns null.
*/
function getLocalESLintVersion() {
try {
const resolver = new ModuleResolver();
const eslintPath = resolver.resolve("eslint", process.cwd());
const eslint = require(eslintPath);

return eslint.linter.version || null;
} catch (_err) {
return null;
}
}

/**
* Get the shareable config name of the chosen style guide.
* @param {Object} answers The answers object.
* @returns {string} The shareable config name.
*/
function getStyleGuideName(answers) {
if (answers.styleguide === "airbnb" && !answers.airbnbReact) {
return "airbnb-base";
}
return answers.styleguide;
}

/**
* Check whether the local ESLint version conflicts with the required version of the chosen shareable config.
* @param {Object} answers The answers object.
* @returns {boolean} `true` if the local ESLint is found then it conflicts with the required version of the chosen shareable config.
*/
function hasESLintVersionConflict(answers) {

// Get the local ESLint version.
const localESLintVersion = getLocalESLintVersion();

if (!localESLintVersion) {
return false;
}

// Get the required range of ESLint version.
const configName = getStyleGuideName(answers);
const moduleName = `eslint-config-${configName}@latest`;
const requiredESLintVersionRange = getPeerDependencies(moduleName).eslint;

if (!requiredESLintVersionRange) {
return false;
}

answers.localESLintVersion = localESLintVersion;
answers.requiredESLintVersionRange = requiredESLintVersionRange;

// Check the version.
if (semver.satisfies(localESLintVersion, requiredESLintVersionRange)) {
answers.installESLint = false;
return false;
}

return true;
}

/* istanbul ignore next: no need to test inquirer*/
/**
* Ask use a few questions on command prompt
Expand Down Expand Up @@ -346,6 +436,21 @@ function promptUser() {
when(answers) {
return ((answers.source === "guide" && answers.packageJsonExists) || answers.source === "auto");
}
},
{
type: "confirm",
name: "installESLint",
message(answers) {
const verb = semver.ltr(answers.localESLintVersion, answers.requiredESLintVersionRange)
? "upgrade"
: "downgrade";

return `The style guide "${answers.styleguide}" requires eslint@${answers.requiredESLintVersionRange}. You are currently using eslint@${answers.localESLintVersion}.\n Do you want to ${verb}?`;
},
default: true,
when(answers) {
return answers.source === "guide" && answers.packageJsonExists && hasESLintVersionConflict(answers);
}
}
]).then(earlyAnswers => {

Expand All @@ -355,11 +460,14 @@ function promptUser() {
log.info("A package.json is necessary to install plugins such as style guides. Run `npm init` to create a package.json file and try again.");
return void 0;
}
if (earlyAnswers.installESLint === false && !semver.satisfies(earlyAnswers.localESLintVersion, earlyAnswers.requiredESLintVersionRange)) {
log.info(`Note: it might not work since ESLint's version is mismatched with the ${earlyAnswers.styleguide} config.`);
}
if (earlyAnswers.styleguide === "airbnb" && !earlyAnswers.airbnbReact) {
earlyAnswers.styleguide = "airbnb-base";
}

config = getConfigForStyleGuide(earlyAnswers.styleguide);
config = getConfigForStyleGuide(earlyAnswers.styleguide, earlyAnswers.installESLint);
writeFile(config, earlyAnswers.format);

return void 0;
Expand Down Expand Up @@ -479,6 +587,7 @@ function promptUser() {

const init = {
getConfigForStyleGuide,
hasESLintVersionConflict,
processAnswers,
/* istanbul ignore next */initializeConfig() {
return promptUser();
Expand Down
12 changes: 12 additions & 0 deletions tools/eslint/lib/config/plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,20 @@ class Plugins {
* @param {string[]} pluginNames An array of plugins names.
* @returns {void}
* @throws {Error} If a plugin cannot be loaded.
* @throws {Error} If "plugins" in config is not an array
*/
loadAll(pluginNames) {

// if "plugins" in config is not an array, throw an error so user can fix their config.
if (!Array.isArray(pluginNames)) {
const pluginNotArrayMessage = "ESLint configuration error: \"plugins\" value must be an array";

debug(`${pluginNotArrayMessage}: ${JSON.stringify(pluginNames)}`);

throw new Error(pluginNotArrayMessage);
}

// load each plugin by name
pluginNames.forEach(this.load, this);
}
}
Expand Down
Loading