From f5574dc739fcc74a7841217ba1f31cce02bee1ff Mon Sep 17 00:00:00 2001 From: "Nicholas C. Zakas" Date: Wed, 3 May 2023 08:01:12 -0700 Subject: [PATCH] feat: Add findConfigFile() method to FlatESLint (#17142) Fixes #17046 --- lib/eslint/flat-eslint.js | 67 ++++++++++++++++++++++++--------- tests/lib/eslint/flat-eslint.js | 37 ++++++++++++++++++ 2 files changed, 86 insertions(+), 18 deletions(-) diff --git a/lib/eslint/flat-eslint.js b/lib/eslint/flat-eslint.js index d88cf178233..49228f16e05 100644 --- a/lib/eslint/flat-eslint.js +++ b/lib/eslint/flat-eslint.js @@ -321,26 +321,15 @@ async function loadFlatConfigFile(filePath) { } /** - * Calculates the config array for this run based on inputs. - * @param {FlatESLint} eslint The instance to create the config array for. + * Determines which config file to use. This is determined by seeing if an + * override config file was passed, and if so, using it; otherwise, as long + * as override config file is not explicitly set to `false`, it will search + * upwards from the cwd for a file named `eslint.config.js`. * @param {import("./eslint").ESLintOptions} options The ESLint instance options. - * @returns {FlatConfigArray} The config array for `eslint``. + * @returns {{configFilePath:string,basePath:string}} Location information for + * the config file. */ -async function calculateConfigArray(eslint, { - cwd, - baseConfig, - overrideConfig, - configFile, - ignore: shouldIgnore, - ignorePatterns -}) { - - // check for cached instance - const slots = privateMembers.get(eslint); - - if (slots.configs) { - return slots.configs; - } +async function locateConfigFileToUse({ configFile, cwd }) { // determine where to load config file from let configFilePath; @@ -360,7 +349,36 @@ async function calculateConfigArray(eslint, { basePath = path.resolve(path.dirname(configFilePath)); } + return { + configFilePath, + basePath + }; + +} +/** + * Calculates the config array for this run based on inputs. + * @param {FlatESLint} eslint The instance to create the config array for. + * @param {import("./eslint").ESLintOptions} options The ESLint instance options. + * @returns {FlatConfigArray} The config array for `eslint``. + */ +async function calculateConfigArray(eslint, { + cwd, + baseConfig, + overrideConfig, + configFile, + ignore: shouldIgnore, + ignorePatterns +}) { + + // check for cached instance + const slots = privateMembers.get(eslint); + + if (slots.configs) { + return slots.configs; + } + + const { configFilePath, basePath } = await locateConfigFileToUse({ configFile, cwd }); const configs = new FlatConfigArray(baseConfig || [], { basePath, shouldIgnore }); // load config file @@ -1160,6 +1178,19 @@ class FlatESLint { return configs.getConfig(absolutePath); } + /** + * Finds the config file being used by this instance based on the options + * passed to the constructor. + * @returns {string|undefined} The path to the config file being used or + * `undefined` if no config file is being used. + */ + async findConfigFile() { + const options = privateMembers.get(this).options; + const { configFilePath } = await locateConfigFileToUse(options); + + return configFilePath; + } + /** * Checks if a given path is ignored by ESLint. * @param {string} filePath The path of the file to check. diff --git a/tests/lib/eslint/flat-eslint.js b/tests/lib/eslint/flat-eslint.js index d79e4f92d4b..0eea528a12c 100644 --- a/tests/lib/eslint/flat-eslint.js +++ b/tests/lib/eslint/flat-eslint.js @@ -3954,6 +3954,43 @@ describe("FlatESLint", () => { }); }); + describe("findConfigFile()", () => { + + it("should return null when overrideConfigFile is true", async () => { + const engine = new FlatESLint({ + overrideConfigFile: true + }); + + assert.strictEqual(await engine.findConfigFile(), void 0); + }); + + it("should return custom config file path when overrideConfigFile is a nonempty string", async () => { + const engine = new FlatESLint({ + overrideConfigFile: "my-config.js" + }); + const configFilePath = path.resolve(__dirname, "../../../my-config.js"); + + assert.strictEqual(await engine.findConfigFile(), configFilePath); + }); + + it("should return root level eslint.config.js when overrideConfigFile is null", async () => { + const engine = new FlatESLint({ + overrideConfigFile: null + }); + const configFilePath = path.resolve(__dirname, "../../../eslint.config.js"); + + assert.strictEqual(await engine.findConfigFile(), configFilePath); + }); + + it("should return root level eslint.config.js when overrideConfigFile is not specified", async () => { + const engine = new FlatESLint(); + const configFilePath = path.resolve(__dirname, "../../../eslint.config.js"); + + assert.strictEqual(await engine.findConfigFile(), configFilePath); + }); + + }); + describe("getRulesMetaForResults()", () => { it("should throw an error when this instance did not lint any files", async () => {