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

Fix: rule deprecation warnings did not consider all rules #11044

Merged
merged 2 commits into from Nov 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
107 changes: 59 additions & 48 deletions lib/cli-engine.js
Expand Up @@ -22,6 +22,7 @@ const fs = require("fs"),
lodash = require("lodash"),
IgnoredPaths = require("./ignored-paths"),
Config = require("./config"),
ConfigOps = require("./config/config-ops"),
LintResultCache = require("./util/lint-result-cache"),
globUtils = require("./util/glob-utils"),
validator = require("./config/config-validator"),
Expand Down Expand Up @@ -143,7 +144,7 @@ function calculateStatsPerRun(results) {
* @param {boolean} allowInlineConfig Allow/ignore comments that change config.
* @param {boolean} reportUnusedDisableDirectives Allow/ignore comments that change config.
* @param {Linter} linter Linter context
* @returns {LintResult} The results for linting on this text.
* @returns {{rules: LintResult, config: Object}} The results for linting on this text and the fully-resolved config for it.
* @private
*/
function processText(text, configHelper, filename, fix, allowInlineConfig, reportUnusedDisableDirectives, linter) {
Expand Down Expand Up @@ -204,7 +205,7 @@ function processText(text, configHelper, filename, fix, allowInlineConfig, repor
result.source = text;
}

return result;
return { result, config };
}

/**
Expand All @@ -214,24 +215,22 @@ function processText(text, configHelper, filename, fix, allowInlineConfig, repor
* @param {Object} configHelper The configuration options for ESLint.
* @param {Object} options The CLIEngine options object.
* @param {Linter} linter Linter context
* @returns {LintResult} The results for linting on this file.
* @returns {{rules: LintResult, config: Object}} The results for linting on this text and the fully-resolved config for it.
* @private
*/
function processFile(filename, configHelper, options, linter) {

const text = fs.readFileSync(path.resolve(filename), "utf8"),
result = processText(
text,
configHelper,
filename,
options.fix,
options.allowInlineConfig,
options.reportUnusedDisableDirectives,
linter
);

return result;

const text = fs.readFileSync(path.resolve(filename), "utf8");

return processText(
text,
configHelper,
filename,
options.fix,
options.allowInlineConfig,
options.reportUnusedDisableDirectives,
linter
);
}

/**
Expand Down Expand Up @@ -275,32 +274,30 @@ function createIgnoreResult(filePath, baseDir) {

/**
* Produces rule warnings (i.e. deprecation) from configured rules
* @param {Object} rules - Rules configured
* @param {(Array<string>|Set<string>)} usedRules - Rules configured
* @param {Map} loadedRules - Map of loaded rules
* @returns {Object} Contains rule warnings
* @returns {Array<Object>} Contains rule warnings
* @private
*/
function createRuleWarnings(rules, loadedRules) {
const ruleWarnings = { usedDeprecatedRules: [] };

if (rules) {
Object.keys(rules).forEach(name => {
const loadedRule = loadedRules.get(name);
function createRuleDeprecationWarnings(usedRules, loadedRules) {
const usedDeprecatedRules = [];

if (loadedRule.meta && loadedRule.meta.deprecated) {
const deprecatedRule = { ruleId: name };
const replacedBy = lodash.get(loadedRule, "meta.replacedBy", []);
usedRules.forEach(name => {
const loadedRule = loadedRules.get(name);

if (replacedBy.every(newRule => lodash.isString(newRule))) {
deprecatedRule.replacedBy = replacedBy;
}
if (loadedRule && loadedRule.meta && loadedRule.meta.deprecated) {
const deprecatedRule = { ruleId: name };
const replacedBy = lodash.get(loadedRule, "meta.replacedBy", []);

ruleWarnings.usedDeprecatedRules.push(deprecatedRule);
if (replacedBy.every(newRule => lodash.isString(newRule))) {
deprecatedRule.replacedBy = replacedBy;
}
});
}

return ruleWarnings;
usedDeprecatedRules.push(deprecatedRule);
}
});

return usedDeprecatedRules;
}

/**
Expand Down Expand Up @@ -541,6 +538,7 @@ class CLIEngine {

const startTime = Date.now();
const fileList = globUtils.listFilesToProcess(patterns, options);
const allUsedRules = new Set();
const results = fileList.map(fileInfo => {
if (fileInfo.ignored) {
return createIgnoreResult(fileInfo.filename, options.cwd);
Expand All @@ -564,7 +562,13 @@ class CLIEngine {

debug(`Processing ${fileInfo.filename}`);

return processFile(fileInfo.filename, configHelper, options, this.linter);
const { result, config } = processFile(fileInfo.filename, configHelper, options, this.linter);

Object.keys(config.rules)
.filter(ruleId => ConfigOps.getRuleSeverity(config.rules[ruleId]))
.forEach(ruleId => allUsedRules.add(ruleId));

return result;
});

if (options.cache) {
Expand All @@ -585,7 +589,7 @@ class CLIEngine {

const stats = calculateStatsPerRun(results);

const ruleWarnings = createRuleWarnings(this.options.rules, this.getRules());
const usedDeprecatedRules = createRuleDeprecationWarnings(allUsedRules, this.getRules());

debug(`Linting complete in: ${Date.now() - startTime}ms`);

Expand All @@ -595,7 +599,7 @@ class CLIEngine {
warningCount: stats.warningCount,
fixableErrorCount: stats.fixableErrorCount,
fixableWarningCount: stats.fixableWarningCount,
usedDeprecatedRules: ruleWarnings.usedDeprecatedRules
usedDeprecatedRules
};
}

Expand All @@ -618,22 +622,28 @@ class CLIEngine {
const resolvedFilename = filename && !path.isAbsolute(filename)
? path.resolve(options.cwd, filename)
: filename;
let usedDeprecatedRules;

if (resolvedFilename && ignoredPaths.contains(resolvedFilename)) {
if (warnIgnored) {
results.push(createIgnoreResult(resolvedFilename, options.cwd));
}
usedDeprecatedRules = [];
} else {
results.push(
processText(
text,
configHelper,
resolvedFilename,
options.fix,
options.allowInlineConfig,
options.reportUnusedDisableDirectives,
this.linter
)
const { result, config } = processText(
text,
configHelper,
resolvedFilename,
options.fix,
options.allowInlineConfig,
options.reportUnusedDisableDirectives,
this.linter
);

results.push(result);
usedDeprecatedRules = createRuleDeprecationWarnings(
Object.keys(config.rules).filter(rule => ConfigOps.getRuleSeverity(config.rules[rule])),
this.getRules()
);
}

Expand All @@ -644,7 +654,8 @@ class CLIEngine {
errorCount: stats.errorCount,
warningCount: stats.warningCount,
fixableErrorCount: stats.fixableErrorCount,
fixableWarningCount: stats.fixableWarningCount
fixableWarningCount: stats.fixableWarningCount,
usedDeprecatedRules
};
}

Expand Down
1 change: 0 additions & 1 deletion packages/eslint-config-eslint/default.yml
Expand Up @@ -53,7 +53,6 @@ rules:
no-async-promise-executor: "error"
no-buffer-constructor: "error"
no-caller: "error"
no-catch-shadow: "error"
no-confusing-arrow: "error"
no-console: "error"
no-delete-var: "error"
Expand Down
@@ -0,0 +1,2 @@
rules:
indent-legacy: error
45 changes: 39 additions & 6 deletions tests/lib/cli-engine.js
Expand Up @@ -299,7 +299,8 @@ describe("CLIEngine", () => {
errorCount: 0,
warningCount: 0,
fixableErrorCount: 0,
fixableWarningCount: 0
fixableWarningCount: 0,
usedDeprecatedRules: []
});
});

Expand Down Expand Up @@ -371,7 +372,8 @@ describe("CLIEngine", () => {
errorCount: 1,
warningCount: 0,
fixableErrorCount: 0,
fixableWarningCount: 0
fixableWarningCount: 0,
usedDeprecatedRules: []
});
});

Expand Down Expand Up @@ -412,7 +414,8 @@ describe("CLIEngine", () => {
errorCount: 1,
warningCount: 0,
fixableErrorCount: 0,
fixableWarningCount: 0
fixableWarningCount: 0,
usedDeprecatedRules: []
});
});

Expand Down Expand Up @@ -453,7 +456,8 @@ describe("CLIEngine", () => {
errorCount: 1,
warningCount: 0,
fixableErrorCount: 0,
fixableWarningCount: 0
fixableWarningCount: 0,
usedDeprecatedRules: []
});
});

Expand Down Expand Up @@ -540,7 +544,8 @@ describe("CLIEngine", () => {
errorCount: 1,
warningCount: 0,
fixableErrorCount: 0,
fixableWarningCount: 0
fixableWarningCount: 0,
usedDeprecatedRules: []
});
});

Expand Down Expand Up @@ -598,6 +603,19 @@ describe("CLIEngine", () => {
assert.strictEqual(report.messages[0].message, "OK");
});
});
it("should warn when deprecated rules are found in a config", () => {
engine = new CLIEngine({
cwd: originalDir,
configFile: "tests/fixtures/cli-engine/deprecated-rule-config/.eslintrc.yml"
});

const report = engine.executeOnText("foo");

assert.deepStrictEqual(
report.usedDeprecatedRules,
[{ ruleId: "indent-legacy", replacedBy: ["indent"] }]
);
});
});

describe("executeOnFiles()", () => {
Expand Down Expand Up @@ -1402,6 +1420,20 @@ describe("CLIEngine", () => {
assert.deepStrictEqual(report.usedDeprecatedRules, []);
});

it("should warn when deprecated rules are found in a config", () => {
engine = new CLIEngine({
cwd: originalDir,
configFile: "tests/fixtures/cli-engine/deprecated-rule-config/.eslintrc.yml"
});

const report = engine.executeOnFiles(["lib/cli*.js"]);

assert.deepStrictEqual(
report.usedDeprecatedRules,
[{ ruleId: "indent-legacy", replacedBy: ["indent"] }]
);
});

describe("Fix Mode", () => {

it("should return fixed text on multiple files when in fix mode", () => {
Expand Down Expand Up @@ -3177,7 +3209,8 @@ describe("CLIEngine", () => {
errorCount: 1,
warningCount: 0,
fixableErrorCount: 0,
fixableWarningCount: 0
fixableWarningCount: 0,
usedDeprecatedRules: []
}
);
});
Expand Down