Skip to content

Commit

Permalink
replace getRules by getRulesForFile (refs eslint/rfcs#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
mysticatea committed Feb 16, 2020
1 parent 3f09215 commit d29f613
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 1 deletion.
34 changes: 34 additions & 0 deletions lib/cli-engine/cli-engine.js
Expand Up @@ -20,6 +20,7 @@ const path = require("path");
const defaultOptions = require("../../conf/default-cli-options");
const pkg = require("../../package.json");
const ConfigOps = require("../shared/config-ops");
const { emitDeprecationWarning } = require("../shared/deprecation-warnings");
const naming = require("../shared/naming");
const ModuleResolver = require("../shared/relative-module-resolver");
const { Linter } = require("../linter");
Expand Down Expand Up @@ -620,7 +621,14 @@ class CLIEngine {
}
}

/**
* Get rules that the last `executeOn*` methods used.
* @returns {Map<string, Rule>} A map of rule Id and rule implementation.
* @deprecated
*/
getRules() {
emitDeprecationWarning("getRules()", "ESLINT_LEGACY_GET_RULES");

const { lastConfigArrays } = internalSlotsMap.get(this);

return new Map(function *() {
Expand Down Expand Up @@ -931,6 +939,32 @@ class CLIEngine {
.toCompatibleObjectAsConfigFileContent();
}

/**
* Returns rule objects for the given file based on the CLI options.
* @param {string} filePath The path of the file to retrieve rules for.
* @returns {Map<string, Rule>} A map of rule ID and rule implementation that is used to lint the file.
*/
getRulesForFile(filePath) {
const { configArrayFactory, options } = internalSlotsMap.get(this);
const absolutePath = path.resolve(options.cwd, filePath);

if (directoryExists(absolutePath)) {
throw Object.assign(
new Error("'filePath' should not be a directory path."),
{ messageTemplate: "print-config-with-directory-path" }
);
}
const configArray = configArrayFactory.getConfigArrayForFile(
absolutePath,
{ ignoreNotFoundError: true }
);

return new Map(function *() {
yield* builtInRules;
yield* configArray.pluginRules;
}());
}

/**
* Checks if a given path is ignored by ESLint.
* @param {string} filePath The path of the file to check.
Expand Down
8 changes: 7 additions & 1 deletion lib/shared/deprecation-warnings.js
Expand Up @@ -25,7 +25,13 @@ const deprecationWarningMessages = {
ESLINT_PERSONAL_CONFIG_SUPPRESS:
"'~/.eslintrc.*' config files have been deprecated. " +
"Please remove it or add 'root:true' to the config files in your " +
"projects in order to avoid loading '~/.eslintrc.*' accidentally."
"projects in order to avoid loading '~/.eslintrc.*' accidentally.",
ESLINT_LEGACY_GET_RULES:
"'CLIEngine::getRules()' method has been deprecated. " +
"ESLint may use plugins that have the same name but different " +
"implementations in each target file. This method will be confused in " +
"such a case. " +
"Please use 'CLIEngine::getRulesForFile(filePath)' method instead."
};

/**
Expand Down
77 changes: 77 additions & 0 deletions tests/lib/cli-engine/cli-engine.js
Expand Up @@ -3760,6 +3760,63 @@ describe("CLIEngine", () => {
});
});

describe("getRulesForFile()", () => {
const root = getFixturePath("get-rules-for-file");

/** @type {typeof CLIEngine} */
let InMemoryCLIEngine;

beforeEach(() => {
InMemoryCLIEngine = defineCLIEngineWithInMemoryFileSystem({
cwd: () => root,
files: {

// `one` directory has own `eslint-plugin-foo`.
"one/node_modules/eslint-plugin-foo/index.js": `exports.rules = {
one: () => ({})
}`,
"one/.eslintrc.json": JSON.stringify({ plugins: ["foo"] }),

// `two` directory has own `eslint-plugin-foo`.
"two/node_modules/eslint-plugin-foo/index.js": `exports.rules = {
two: () => ({})
}`,
"two/.eslintrc.json": JSON.stringify({ plugins: ["foo"] }),

// for `--plugin` test.
"node_modules/eslint-plugin-bar/index.js": `exports.rules = {
bar: () => ({})
}`
}
}).CLIEngine;
});

it("should expose the list of built-in rules, and should not throw not-found error even if no config file.", () => {
const engine = new InMemoryCLIEngine({ cwd: root });

assert(engine.getRulesForFile("test.js").has("no-eval"), "'no-eval' rule is present");
assert(engine.getRulesForFile("test.js").has("eqeqeq"), "'eqeqeq' rule is present");
});

it("should expose the list of plugin rules that '--plugin' option provided.", () => {
const engine = new InMemoryCLIEngine({ cwd: root, plugins: ["bar"] });

assert(engine.getRulesForFile("test.js").has("bar/bar"), "'bar/bar' rule is present");
});

it("should expose the list of plugin rules as being relative to the file.", () => {
const engine = new InMemoryCLIEngine({ cwd: root });

assert(!engine.getRulesForFile("test.js").has("foo/one"), "'foo/one' rule is NOT present for 'test.js'");
assert(!engine.getRulesForFile("test.js").has("foo/two"), "'foo/two' rule is NOT present for 'test.js'");
assert(engine.getRulesForFile("one/test.js").has("foo/one"), "'foo/one' rule is present for 'one/test.js'");
assert(!engine.getRulesForFile("one/test.js").has("foo/two"), "'foo/two' rule is NOT present for 'one/test.js'");
assert(!engine.getRulesForFile("two/test.js").has("foo/one"), "'foo/one' rule is NOT present for 'two/test.js'");
assert(engine.getRulesForFile("two/test.js").has("foo/two"), "'foo/two' rule is present for 'two/test.js'");
});

});

describe("isPathIgnored", () => {
it("should check if the given path is ignored", () => {
const engine = new CLIEngine({
Expand Down Expand Up @@ -4495,6 +4552,26 @@ describe("CLIEngine", () => {
});

describe("getRules()", () => {
it("should emit deprecation warning on called.", async() => {
const warningListener = sinon.spy();

process.on("warning", warningListener);
try {
const engine = new CLIEngine();

engine.getRules();
engine.getRules();

// Wait for event emission.
await new Promise(resolve => setTimeout(resolve, 0));

assert.strictEqual(warningListener.callCount, 1);
assert.strictEqual(warningListener.args[0][0].code, "ESLINT_LEGACY_GET_RULES");
} finally {
process.removeListener("warning", warningListener);
}
});

it("should expose the list of rules", () => {
const engine = new CLIEngine();

Expand Down

0 comments on commit d29f613

Please sign in to comment.