Skip to content

Commit

Permalink
tools: update to ESLint 4.3.0
Browse files Browse the repository at this point in the history
PR-URL: #14417
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Teddy Katz <teddy.katz@gmail.com>
Reviewed-By: Roman Reiss <me@silverwind.io>
Reviewed-By: Refael Ackermann <refack@gmail.com>
  • Loading branch information
Trott authored and MylesBorins committed Sep 5, 2017
1 parent 438a642 commit 31f572c
Show file tree
Hide file tree
Showing 304 changed files with 28,501 additions and 15,865 deletions.
9 changes: 5 additions & 4 deletions tools/eslint/bin/eslint.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ 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.message);
console.error(err.stack);
}

process.exitCode = 1;
Expand Down
4 changes: 2 additions & 2 deletions tools/eslint/conf/category-list.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
],
"deprecated": {
"name": "Deprecated",
"description": "These rules have been deprecated and replaced by newer rules:",
"description": "These rules have been deprecated in accordance with the [deprecation policy](/docs/user-guide/rule-deprecation), and replaced by newer rules:",
"rules": []
},
"removed": {
"name": "Removed",
"description": "These rules from older versions of ESLint have been replaced by newer rules:",
"description": "These rules from older versions of ESLint (before the [deprecation policy](/docs/user-guide/rule-deprecation) existed) have been replaced by newer rules:",
"rules": [
{ "removed": "generator-star", "replacedBy": ["generator-star-spacing"] },
{ "removed": "global-strict", "replacedBy": ["strict"] },
Expand Down
4 changes: 3 additions & 1 deletion tools/eslint/conf/config-schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ const baseConfigProperties = {
parserOptions: { type: "object" },
plugins: { type: "array" },
rules: { type: "object" },
settings: { type: "object" }
settings: { type: "object" },

ecmaFeatures: { type: "object" } // deprecated; logs a warning when used
};

const overrideProperties = Object.assign(
Expand Down
25 changes: 11 additions & 14 deletions tools/eslint/conf/eslint-recommended.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@

"use strict";

/* eslint sort-keys: ["error", "asc"], quote-props: ["error", "consistent"] */
/* eslint-disable sort-keys */
/* eslint sort-keys: ["error", "asc"] */

module.exports = {
rules: {

/* eslint-enable sort-keys */
"accessor-pairs": "off",
"array-bracket-newline": "off",
"array-bracket-spacing": "off",
Expand All @@ -25,23 +22,23 @@ module.exports = {
"block-spacing": "off",
"brace-style": "off",
"callback-return": "off",
"camelcase": "off",
camelcase: "off",
"capitalized-comments": "off",
"class-methods-use-this": "off",
"comma-dangle": "off",
"comma-spacing": "off",
"comma-style": "off",
"complexity": "off",
complexity: "off",
"computed-property-spacing": "off",
"consistent-return": "off",
"consistent-this": "off",
"constructor-super": "error",
"curly": "off",
curly: "off",
"default-case": "off",
"dot-location": "off",
"dot-notation": "off",
"eol-last": "off",
"eqeqeq": "off",
eqeqeq: "off",
"for-direction": "off",
"func-call-spacing": "off",
"func-name-matching": "off",
Expand All @@ -55,7 +52,7 @@ module.exports = {
"id-blacklist": "off",
"id-length": "off",
"id-match": "off",
"indent": "off",
indent: "off",
"indent-legacy": "off",
"init-declarations": "off",
"jsx-quotes": "off",
Expand Down Expand Up @@ -234,13 +231,13 @@ module.exports = {
"prefer-spread": "off",
"prefer-template": "off",
"quote-props": "off",
"quotes": "off",
"radix": "off",
quotes: "off",
radix: "off",
"require-await": "off",
"require-jsdoc": "off",
"require-yield": "error",
"rest-spread-spacing": "off",
"semi": "off",
semi: "off",
"semi-spacing": "off",
"semi-style": "off",
"sort-imports": "off",
Expand All @@ -252,7 +249,7 @@ module.exports = {
"space-infix-ops": "off",
"space-unary-ops": "off",
"spaced-comment": "off",
"strict": "off",
strict: "off",
"switch-colon-spacing": "off",
"symbol-description": "off",
"template-curly-spacing": "off",
Expand All @@ -265,6 +262,6 @@ module.exports = {
"wrap-iife": "off",
"wrap-regex": "off",
"yield-star-spacing": "off",
"yoda": "off"
yoda: "off"
}
};
10 changes: 5 additions & 5 deletions tools/eslint/lib/config/config-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
* @author Nicholas C. Zakas
*/

/* eslint no-use-before-define: 0 */

"use strict";

//------------------------------------------------------------------------------
Expand Down Expand Up @@ -418,6 +416,8 @@ function applyExtends(config, configContext, filePath, relativeTo) {
);
}
debug(`Loading ${parentPath}`);

// eslint-disable-next-line no-use-before-define
return ConfigOps.merge(load(parentPath, configContext, relativeTo), previousValue);
} catch (e) {

Expand Down Expand Up @@ -502,8 +502,8 @@ function resolve(filePath, relativeTo) {

if (filePath.startsWith("plugin:")) {
const configFullName = filePath;
const pluginName = filePath.substr(7, filePath.lastIndexOf("/") - 7);
const configName = filePath.substr(filePath.lastIndexOf("/") + 1, filePath.length - filePath.lastIndexOf("/") - 1);
const pluginName = filePath.slice(7, filePath.lastIndexOf("/"));
const configName = filePath.slice(filePath.lastIndexOf("/") + 1);

normalizedPackageName = normalizePackageName(pluginName, "eslint-plugin");
debug(`Attempting to resolve ${normalizedPackageName}`);
Expand Down Expand Up @@ -546,7 +546,7 @@ function loadFromDisk(resolvedPath, configContext) {
}

// validate the configuration before continuing
validator.validate(config, resolvedPath, configContext.linterContext.rules, configContext.linterContext.environments);
validator.validate(config, resolvedPath.configFullName, configContext.linterContext.rules, configContext.linterContext.environments);

/*
* If an `extends` property is defined, it represents a configuration file to use as
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

0 comments on commit 31f572c

Please sign in to comment.