From a1181efcc74cb0a24a39b9066c39db90b91fdf3b Mon Sep 17 00:00:00 2001 From: Zhao DAI Date: Sun, 13 Feb 2022 13:37:31 +0000 Subject: [PATCH 1/3] fix: Avoid dirname for built-in configs. Load eslint:recommended and eslint:all configs via import instead file paths. Fixes: https://github.com/eslint/eslint/issues/15575 --- lib/cascading-config-array-factory.js | 28 +-- lib/config-array-factory.js | 37 ++-- lib/flat-compat.js | 13 +- package.json | 1 + rollup.config.js | 8 +- tests/lib/cascading-config-array-factory.js | 227 ++++++++++---------- tests/lib/config-array-factory.js | 43 ++-- 7 files changed, 186 insertions(+), 171 deletions(-) diff --git a/lib/cascading-config-array-factory.js b/lib/cascading-config-array-factory.js index 553ca0a9..cf902adc 100644 --- a/lib/cascading-config-array-factory.js +++ b/lib/cascading-config-array-factory.js @@ -22,13 +22,18 @@ // Requirements //------------------------------------------------------------------------------ +import debugOrig from "debug"; import os from "os"; import path from "path"; + +import { ConfigArrayFactory } from "./config-array-factory.js"; +import { + ConfigArray, + ConfigDependency, + IgnorePattern +} from "./config-array/index.js"; import ConfigValidator from "./shared/config-validator.js"; import { emitDeprecationWarning } from "./shared/deprecation-warnings.js"; -import { ConfigArrayFactory } from "./config-array-factory.js"; -import { ConfigArray, ConfigDependency, IgnorePattern } from "./config-array/index.js"; -import debugOrig from "debug"; const debug = debugOrig("eslintrc:cascading-config-array-factory"); @@ -56,8 +61,8 @@ const debug = debugOrig("eslintrc:cascading-config-array-factory"); * @property {Function} loadRules The function to use to load rules. * @property {Map} builtInRules The rules that are built in to ESLint. * @property {Object} [resolver=ModuleResolver] The module resolver object. - * @property {string} eslintAllPath The path to the definitions for eslint:all. - * @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended. + * @property {ConfigData} eslintAllConfig The config data to the definitions for eslint:all. + * @property {ConfigData} eslintRecommendedConfig The config data to the definitions for eslint:recommended. */ /** @@ -77,8 +82,8 @@ const debug = debugOrig("eslintrc:cascading-config-array-factory"); * @property {Function} loadRules The function to use to load rules. * @property {Map} builtInRules The rules that are built in to ESLint. * @property {Object} [resolver=ModuleResolver] The module resolver object. - * @property {string} eslintAllPath The path to the definitions for eslint:all. - * @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended. + * @property {ConfigData} eslintAllConfig The config data to the definitions for eslint:all. + * @property {ConfigData} eslintRecommendedConfig The config data to the definitions for eslint:recommended. */ /** @type {WeakMap} */ @@ -218,8 +223,8 @@ class CascadingConfigArrayFactory { builtInRules = new Map(), loadRules, resolver, - eslintRecommendedPath, - eslintAllPath + eslintRecommendedConfig, + eslintAllConfig } = {}) { const configArrayFactory = new ConfigArrayFactory({ additionalPluginPool, @@ -227,8 +232,8 @@ class CascadingConfigArrayFactory { resolvePluginsRelativeTo, builtInRules, resolver, - eslintRecommendedPath, - eslintAllPath + eslintRecommendedConfig, + eslintAllConfig }); internalSlotsMap.set(this, { @@ -516,5 +521,4 @@ class CascadingConfigArrayFactory { //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ - export { CascadingConfigArrayFactory }; diff --git a/lib/config-array-factory.js b/lib/config-array-factory.js index b571e2f7..1c8de773 100644 --- a/lib/config-array-factory.js +++ b/lib/config-array-factory.js @@ -38,22 +38,23 @@ // Requirements //------------------------------------------------------------------------------ +import debugOrig from "debug"; import fs from "fs"; -import path from "path"; import importFresh from "import-fresh"; +import { createRequire } from "module"; +import path from "path"; import stripComments from "strip-json-comments"; -import ConfigValidator from "./shared/config-validator.js"; -import * as naming from "./shared/naming.js"; -import * as ModuleResolver from "./shared/relative-module-resolver.js"; + import { ConfigArray, ConfigDependency, IgnorePattern, OverrideTester } from "./config-array/index.js"; -import debugOrig from "debug"; +import ConfigValidator from "./shared/config-validator.js"; +import * as naming from "./shared/naming.js"; +import * as ModuleResolver from "./shared/relative-module-resolver.js"; -import { createRequire } from "module"; const require = createRequire(import.meta.url); const debug = debugOrig("eslintrc:config-array-factory"); @@ -89,8 +90,8 @@ const configFilenames = [ * @property {string} [resolvePluginsRelativeTo] A path to the directory that plugins should be resolved from. Defaults to `cwd`. * @property {Map} builtInRules The rules that are built in to ESLint. * @property {Object} [resolver=ModuleResolver] The module resolver object. - * @property {string} eslintAllPath The path to the definitions for eslint:all. - * @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended. + * @property {import("./shared/types").ConfigData} eslintAllConfig The config data to the definitions for eslint:all. + * @property {import("./shared/types").ConfigData} eslintRecommendedConfig The config data to the definitions for eslint:recommended. */ /** @@ -100,8 +101,8 @@ const configFilenames = [ * @property {string | undefined} resolvePluginsRelativeTo An absolute path the the directory that plugins should be resolved from. * @property {Map} builtInRules The rules that are built in to ESLint. * @property {Object} [resolver=ModuleResolver] The module resolver object. - * @property {string} eslintAllPath The path to the definitions for eslint:all. - * @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended. + * @property {import("./shared/types").ConfigData} eslintAllConfig The config data to the definitions for eslint:all. + * @property {import("./shared/types").ConfigData} eslintRecommendedConfig The config data to the definitions for eslint:recommended. */ /** @@ -427,8 +428,8 @@ class ConfigArrayFactory { resolvePluginsRelativeTo, builtInRules, resolver = ModuleResolver, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig } = {}) { internalSlotsMap.set(this, { additionalPluginPool, @@ -438,8 +439,8 @@ class ConfigArrayFactory { path.resolve(cwd, resolvePluginsRelativeTo), builtInRules, resolver, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); } @@ -797,19 +798,17 @@ class ConfigArrayFactory { * @private */ _loadExtendedBuiltInConfig(extendName, ctx) { - const { eslintAllPath, eslintRecommendedPath } = internalSlotsMap.get(this); + const { eslintAllConfig, eslintRecommendedConfig } = internalSlotsMap.get(this); if (extendName === "eslint:recommended") { - return this._loadConfigData({ + return this._normalizeConfigData(eslintRecommendedConfig, { ...ctx, - filePath: eslintRecommendedPath, name: `${ctx.name} » ${extendName}` }); } if (extendName === "eslint:all") { - return this._loadConfigData({ + return this._normalizeConfigData(eslintAllConfig, { ...ctx, - filePath: eslintAllPath, name: `${ctx.name} » ${extendName}` }); } diff --git a/lib/flat-compat.js b/lib/flat-compat.js index 7fa111d3..f043741f 100644 --- a/lib/flat-compat.js +++ b/lib/flat-compat.js @@ -7,14 +7,13 @@ // Requirements //----------------------------------------------------------------------------- -import path from "path"; -import { fileURLToPath } from "url"; import createDebug from "debug"; +import path from "path"; -import { ConfigArrayFactory } from "./config-array-factory.js"; import environments from "../conf/environments.js"; - -const dirname = path.dirname(fileURLToPath(import.meta.url)); +import eslintAllConfig from "../conf/eslint-all.cjs"; +import eslintRecommendedConfig from "../conf/eslint-recommended.cjs"; +import { ConfigArrayFactory } from "./config-array-factory.js"; //----------------------------------------------------------------------------- // Helpers @@ -225,8 +224,8 @@ class FlatCompat { this[cafactory] = new ConfigArrayFactory({ cwd: baseDirectory, resolvePluginsRelativeTo, - eslintAllPath: path.resolve(dirname, "../conf/eslint-all.cjs"), - eslintRecommendedPath: path.resolve(dirname, "../conf/eslint-recommended.cjs") + eslintAllConfig, + eslintRecommendedConfig }); } diff --git a/package.json b/package.json index a8d914fa..39177a36 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ }, "homepage": "https://github.com/eslint/eslintrc#readme", "devDependencies": { + "@rollup/plugin-commonjs": "^21.0.1", "c8": "^7.7.3", "chai": "^4.3.4", "eslint": "^7.31.0", diff --git a/rollup.config.js b/rollup.config.js index 3ada0c1c..dee130f0 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,3 +1,5 @@ +import commonjs from "@rollup/plugin-commonjs"; + export default [ { input: "./lib/index.js", @@ -12,7 +14,8 @@ export default [ file: "dist/eslintrc.cjs", sourcemap: true, freeze: false - } + }, + plugins: [commonjs()] }, { input: "./lib/index-universal.js", @@ -27,6 +30,7 @@ export default [ file: "dist/eslintrc-universal.cjs", sourcemap: true, freeze: false - } + }, + plugins: [commonjs()] } ]; diff --git a/tests/lib/cascading-config-array-factory.js b/tests/lib/cascading-config-array-factory.js index 64b70395..593fa66b 100644 --- a/tests/lib/cascading-config-array-factory.js +++ b/tests/lib/cascading-config-array-factory.js @@ -7,17 +7,19 @@ // Requirements //----------------------------------------------------------------------------- +import { assert } from "chai"; import fs from "fs"; -import path from "path"; -import { fileURLToPath } from "url"; import os from "os"; -import { assert } from "chai"; +import path from "path"; import sh from "shelljs"; import sinon from "sinon"; import systemTempDir from "temp-dir"; +import { fileURLToPath } from "url"; import { Legacy } from "../../lib/index.js"; import { createCustomTeardown } from "../_utils/index.js"; +import eslintAllConfig from "../fixtures/eslint-all.cjs"; +import eslintRecommendedConfig from "../fixtures/eslint-recommended.cjs"; const dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -38,9 +40,6 @@ const cwdIgnorePatterns = new ConfigArrayFactory() .ignorePattern .patterns; -const eslintAllPath = path.resolve(dirname, "../fixtures/eslint-all.cjs"); -const eslintRecommendedPath = path.resolve(dirname, "../fixtures/eslint-recommended.cjs"); - //----------------------------------------------------------------------------- // Tests //----------------------------------------------------------------------------- @@ -657,8 +656,8 @@ describe("CascadingConfigArrayFactory", () => { cwd: fixtureDir, baseConfig: customBaseConfig, useEslintrc: false, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const config = getConfig(factory); @@ -677,8 +676,8 @@ describe("CascadingConfigArrayFactory", () => { // TODO: Tests should not rely on project files!!! it("should return the project config when called in current working directory", () => { const factory = new CascadingConfigArrayFactory({ - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const actual = getConfig(factory); @@ -689,8 +688,8 @@ describe("CascadingConfigArrayFactory", () => { const firstpath = path.resolve(dirname, "../fixtures/configurations/single-quotes/subdir/.eslintrc"); const secondpath = path.resolve(dirname, "../fixtures/configurations/single-quotes/.eslintrc"); const factory = new CascadingConfigArrayFactory({ - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); let config; @@ -703,8 +702,8 @@ describe("CascadingConfigArrayFactory", () => { it("should throw error when a configuration file doesn't exist", () => { const configPath = path.resolve(dirname, "../fixtures/configurations/.eslintrc"); const factory = new CascadingConfigArrayFactory({ - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); sinon.stub(fs, "readFileSync").throws(new Error()); @@ -718,8 +717,8 @@ describe("CascadingConfigArrayFactory", () => { it("should throw error when a configuration file is not require-able", () => { const configPath = ".eslintrc"; const factory = new CascadingConfigArrayFactory({ - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); sinon.stub(fs, "readFileSync").throws(new Error()); @@ -735,8 +734,8 @@ describe("CascadingConfigArrayFactory", () => { const configArrayFactory = new ConfigArrayFactory(); const factory = new CascadingConfigArrayFactory({ configArrayFactory, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); sinon.spy(configArrayFactory, "loadInDirectory"); @@ -756,8 +755,8 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath, useEslintrc: false, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const config = getConfig(factory); const { semi, strict } = config.rules; @@ -772,8 +771,8 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath, useEslintrc: false, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const config = getConfig(factory); const { "no-alert": noAlert, "no-undef": noUndef } = config.rules; @@ -785,8 +784,8 @@ describe("CascadingConfigArrayFactory", () => { it("should contain the correct value for parser when a custom parser is specified", () => { const configPath = path.resolve(dirname, "../fixtures/configurations/parser/.eslintrc.json"); const factory = new CascadingConfigArrayFactory({ - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const config = getConfig(factory, configPath); @@ -800,8 +799,8 @@ describe("CascadingConfigArrayFactory", () => { it("should correctly merge environment settings", () => { const factory = new CascadingConfigArrayFactory({ useEslintrc: true, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const file = getFixturePath("envs", "sub", "foo.js"); const expected = { @@ -821,8 +820,8 @@ describe("CascadingConfigArrayFactory", () => { it("should return a blank config when using no .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ useEslintrc: false, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const file = getFixturePath("broken", "console-wrong-quotes.js"); const expected = { @@ -840,8 +839,8 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ baseConfig: false, useEslintrc: false, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const file = getFixturePath("broken", "console-wrong-quotes.js"); const expected = { @@ -859,8 +858,8 @@ describe("CascadingConfigArrayFactory", () => { it("should return an empty config when not using .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ useEslintrc: false, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const file = getFixturePath("broken", "console-wrong-quotes.js"); const actual = getConfig(factory, file); @@ -879,8 +878,8 @@ describe("CascadingConfigArrayFactory", () => { } }, useEslintrc: false, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const file = getFixturePath("broken", "console-wrong-quotes.js"); const expected = { @@ -910,8 +909,8 @@ describe("CascadingConfigArrayFactory", () => { }, cwd: getFixturePath("plugins"), useEslintrc: false, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const file = getFixturePath("broken", "plugins", "console-wrong-quotes.js"); const expected = { @@ -931,8 +930,8 @@ describe("CascadingConfigArrayFactory", () => { // Project configuration - second level .eslintrc it("should merge configs when local .eslintrc overrides parent .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const file = getFixturePath("broken", "subbroken", "console-wrong-quotes.js"); const expected = { @@ -953,8 +952,8 @@ describe("CascadingConfigArrayFactory", () => { // Project configuration - third level .eslintrc it("should merge configs when local .eslintrc overrides parent and grandparent .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const file = getFixturePath("broken", "subbroken", "subsubbroken", "console-wrong-quotes.js"); const expected = { @@ -975,8 +974,8 @@ describe("CascadingConfigArrayFactory", () => { // Project configuration - root set in second level .eslintrc it("should not return or traverse configurations in parents of config with root:true", () => { const factory = new CascadingConfigArrayFactory({ - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const file = getFixturePath("root-true", "parent", "root", "wrong-semi.js"); const expected = { @@ -994,8 +993,8 @@ describe("CascadingConfigArrayFactory", () => { it("should return project config when called with a relative path from a subdir", () => { const factory = new CascadingConfigArrayFactory({ cwd: getFixturePath("root-true", "parent", "root", "subdir"), - eslintRecommendedPath, - eslintAllPath + eslintRecommendedConfig, + eslintAllConfig }); const dir = "."; const expected = { @@ -1012,8 +1011,8 @@ describe("CascadingConfigArrayFactory", () => { it("should merge command line config when config file adds to local .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath: getFixturePath("broken", "add-conf.yaml"), - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const file = getFixturePath("broken", "console-wrong-quotes.js"); const expected = { @@ -1035,8 +1034,8 @@ describe("CascadingConfigArrayFactory", () => { it("should merge command line config when config file overrides local .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath: getFixturePath("broken", "override-conf.yaml"), - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const file = getFixturePath("broken", "console-wrong-quotes.js"); const expected = { @@ -1057,8 +1056,8 @@ describe("CascadingConfigArrayFactory", () => { it("should merge command line config when config file adds to local and parent .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath: getFixturePath("broken", "add-conf.yaml"), - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const file = getFixturePath("broken", "subbroken", "console-wrong-quotes.js"); const expected = { @@ -1081,8 +1080,8 @@ describe("CascadingConfigArrayFactory", () => { it("should merge command line config when config file overrides local and parent .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath: getFixturePath("broken", "override-conf.yaml"), - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const file = getFixturePath("broken", "subbroken", "console-wrong-quotes.js"); const expected = { @@ -1109,8 +1108,8 @@ describe("CascadingConfigArrayFactory", () => { } }, specificConfigPath: getFixturePath("broken", "override-conf.yaml"), - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const file = getFixturePath("broken", "console-wrong-quotes.js"); const expected = { @@ -1135,8 +1134,8 @@ describe("CascadingConfigArrayFactory", () => { }, cwd: getFixturePath("plugins"), resolvePluginsRelativeTo: getFixturePath("plugins"), - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const file = getFixturePath("broken", "plugins", "console-wrong-quotes.js"); const expected = { @@ -1159,8 +1158,8 @@ describe("CascadingConfigArrayFactory", () => { it("should merge multiple different config file formats", () => { const factory = new CascadingConfigArrayFactory({ - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const file = getFixturePath("fileexts/subdir/subsubdir/foo.js"); const expected = { @@ -1184,8 +1183,8 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath: configPath, useEslintrc: false, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const expected = { globals: { @@ -1203,8 +1202,8 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath: configPath, useEslintrc: false, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const config = getConfig(factory, configPath); @@ -1215,8 +1214,8 @@ describe("CascadingConfigArrayFactory", () => { const configPath = path.resolve(dirname, "../fixtures/configurations/env-node.json"); const factory = new CascadingConfigArrayFactory({ specificConfigPath: configPath, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); getConfig(factory, path.resolve(dirname, "../fixtures/configurations/empty/empty.json")); @@ -1230,8 +1229,8 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ useEslintrc: false, specificConfigPath: configPath, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); getConfig(factory, configPath); @@ -1244,8 +1243,8 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ useEslintrc: false, specificConfigPath: configPath, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const expected = { rules: { "no-empty": [1], "comma-dangle": [2], "no-console": [2] }, @@ -1260,8 +1259,8 @@ describe("CascadingConfigArrayFactory", () => { describe("with env in a child configuration file", () => { it("should not overwrite parserOptions of the parent with env of the child", () => { const factory = new CascadingConfigArrayFactory({ - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const targetPath = getFixturePath("overwrite-ecmaFeatures", "child", "foo.js"); const expected = { @@ -1306,8 +1305,8 @@ describe("CascadingConfigArrayFactory", () => { const filePath = getFakeFixturePath("personal-config", "project-without-config", "foo.js"); const factory = new CascadingConfigArrayFactory({ cwd: projectPath, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); mockOsHomedir(homePath); @@ -1328,8 +1327,8 @@ describe("CascadingConfigArrayFactory", () => { const filePath = getFakeFixturePath("personal-config", "home-folder", "project", "foo.js"); const factory = new CascadingConfigArrayFactory({ cwd: projectPath, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); mockOsHomedir(homePath); @@ -1352,8 +1351,8 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ cwd: projectPath, specificConfigPath: configPath, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); mockOsHomedir(homePath); @@ -1373,8 +1372,8 @@ describe("CascadingConfigArrayFactory", () => { const filePath = getFakeFixturePath("personal-config", "project-with-config", "subfolder", "foo.js"); const factory = new CascadingConfigArrayFactory({ cwd: projectPath, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); mockOsHomedir(projectPath); @@ -1421,8 +1420,8 @@ describe("CascadingConfigArrayFactory", () => { const filePath = getFakeFixturePath("personal-config", "project-without-config", "foo.js"); const factory = new CascadingConfigArrayFactory({ cwd: projectPath, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); mockOsHomedir(homePath); @@ -1438,8 +1437,8 @@ describe("CascadingConfigArrayFactory", () => { const filePath = getFakeFixturePath("personal-config", "project-without-config", "foo.js"); const factory = new CascadingConfigArrayFactory({ cwd: projectPath, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); mockOsHomedir(homePath); @@ -1456,8 +1455,8 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ cwd: projectPath, useEslintrc: false, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); mockOsHomedir(homePath); @@ -1474,8 +1473,8 @@ describe("CascadingConfigArrayFactory", () => { rules: { quotes: [2, "single"] } }, cwd: projectPath, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); mockOsHomedir(homePath); @@ -1490,8 +1489,8 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ baseConfig: {}, cwd: projectPath, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); mockOsHomedir(homePath); @@ -1527,8 +1526,8 @@ describe("CascadingConfigArrayFactory", () => { it("should merge override config when the pattern matches the file name", () => { const factory = new CascadingConfigArrayFactory({ cwd: getPath(), - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const targetPath = getFakeFixturePath("overrides", "foo.js"); const expected = { @@ -1547,8 +1546,8 @@ describe("CascadingConfigArrayFactory", () => { it("should merge override config when the pattern matches the file path relative to the config file", () => { const factory = new CascadingConfigArrayFactory({ cwd: getPath(), - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const targetPath = getFakeFixturePath("overrides", "child", "child-one.js"); const expected = { @@ -1579,8 +1578,8 @@ describe("CascadingConfigArrayFactory", () => { }] }, useEslintrc: false, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }), /Invalid override pattern/u); }); @@ -1597,16 +1596,16 @@ describe("CascadingConfigArrayFactory", () => { }] }, useEslintrc: false, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }), /Invalid override pattern/u); }); it("should merge all local configs (override and non-override) before non-local configs", () => { const factory = new CascadingConfigArrayFactory({ cwd: getPath(), - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const targetPath = getFakeFixturePath("overrides", "two", "child-two.js"); const expected = { @@ -1638,8 +1637,8 @@ describe("CascadingConfigArrayFactory", () => { ] }, useEslintrc: false, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const expected = { rules: { @@ -1664,8 +1663,8 @@ describe("CascadingConfigArrayFactory", () => { }] }, useEslintrc: false, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const expected = { rules: { @@ -1690,8 +1689,8 @@ describe("CascadingConfigArrayFactory", () => { }] }, useEslintrc: false, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const expected = { rules: { @@ -1717,8 +1716,8 @@ describe("CascadingConfigArrayFactory", () => { }] }, useEslintrc: false, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const expected = { rules: {} @@ -1742,8 +1741,8 @@ describe("CascadingConfigArrayFactory", () => { }] }, useEslintrc: false, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const expected = { rules: { @@ -1778,8 +1777,8 @@ describe("CascadingConfigArrayFactory", () => { ] }, useEslintrc: false, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); const expected = { rules: { @@ -1814,8 +1813,8 @@ describe("CascadingConfigArrayFactory", () => { beforeEach(() => { factory = new CascadingConfigArrayFactory({ cwd, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); warning = null; process.on("warning", onWarning); @@ -1956,8 +1955,8 @@ describe("CascadingConfigArrayFactory", () => { cwd: getPath(), additionalPluginPool, cliConfig: { plugins: ["test"] }, - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); }); diff --git a/tests/lib/config-array-factory.js b/tests/lib/config-array-factory.js index 805159fd..373be074 100644 --- a/tests/lib/config-array-factory.js +++ b/tests/lib/config-array-factory.js @@ -7,20 +7,22 @@ // Requirements //----------------------------------------------------------------------------- -import path from "path"; -import { fileURLToPath, pathToFileURL } from "url"; +import { assert } from "chai"; import fs from "fs"; import { createRequire } from "module"; -import { assert } from "chai"; +import path from "path"; import sinon from "sinon"; +import systemTempDir from "temp-dir"; +import { fileURLToPath } from "url"; + import { Legacy } from "../../lib/index.js"; import { createCustomTeardown } from "../_utils/index.js"; -import systemTempDir from "temp-dir"; +import eslintAllConfig from "../fixtures/eslint-all.cjs"; +import eslintRecommendedConfig from "../fixtures/eslint-recommended.cjs"; const require = createRequire(import.meta.url); const fileName = fileURLToPath(import.meta.url); -const dirname = path.dirname(fileName); const { spy } = sinon; const { @@ -34,8 +36,6 @@ const { // Helpers //----------------------------------------------------------------------------- -const eslintAllPath = path.resolve(dirname, "../fixtures/eslint-all.cjs"); -const eslintRecommendedPath = path.resolve(dirname, "../fixtures/eslint-recommended.cjs"); const tempDir = path.join(systemTempDir, "eslintrc/config-array-factory"); /** @@ -953,8 +953,8 @@ describe("ConfigArrayFactory", () => { factory = new ConfigArrayFactory({ cwd: getPath(), - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); }); @@ -1023,8 +1023,7 @@ describe("ConfigArrayFactory", () => { it("should have the config data of 'eslint:all' at the first element.", async () => { assertConfigArrayElement(configArray[0], { name: ".eslintrc » eslint:all", - filePath: eslintAllPath, - ...(await import(pathToFileURL(eslintAllPath))).default + ...eslintAllConfig }); }); @@ -1053,8 +1052,7 @@ describe("ConfigArrayFactory", () => { it("should have the config data of 'eslint:recommended' at the first element.", async () => { assertConfigArrayElement(configArray[0], { name: ".eslintrc » eslint:recommended", - filePath: eslintRecommendedPath, - ...(await import(pathToFileURL(eslintRecommendedPath))).default + ...eslintRecommendedConfig }); }); @@ -1594,8 +1592,8 @@ describe("ConfigArrayFactory", () => { await prepare(); factory = new ConfigArrayFactory({ cwd: getPath(), - eslintAllPath, - eslintRecommendedPath + eslintAllConfig, + eslintRecommendedConfig }); }); @@ -1809,7 +1807,7 @@ describe("ConfigArrayFactory", () => { let cleanup; beforeEach(() => { - cleanup = () => {}; + cleanup = () => { }; }); afterEach(() => cleanup()); @@ -2508,7 +2506,18 @@ env: try { load(factory, "invalid/invalid-top-level-property.yml"); } catch (err) { - assert.include(err.message, `ESLint configuration in ${`invalid${path.sep}invalid-top-level-property.yml`} is invalid`); + + /** + * Received error message is: + * + * ``` + * ESLint configuration: { + * "invalidProperty": 3 + * } in invalid/invalid-top-level-property.yml is invalid: + * - Unexpected top-level property "invalidProperty". + * ``` + */ + assert.include(err.message, `${`invalid${path.sep}invalid-top-level-property.yml`} is invalid`); return; } assert.fail(); From a3bfe57215d8e3853831669b839552f6fae6a756 Mon Sep 17 00:00:00 2001 From: Zhao DAI Date: Wed, 16 Feb 2022 12:14:32 +0000 Subject: [PATCH 2/3] Fix reviews. --- lib/cascading-config-array-factory.js | 25 ++- lib/config-array-factory.js | 51 +++-- lib/flat-compat.js | 6 +- package.json | 1 - rollup.config.js | 8 +- tests/lib/cascading-config-array-factory.js | 237 +++++++++++--------- tests/lib/config-array-factory.js | 55 +++-- 7 files changed, 219 insertions(+), 164 deletions(-) diff --git a/lib/cascading-config-array-factory.js b/lib/cascading-config-array-factory.js index cf902adc..4b575c2d 100644 --- a/lib/cascading-config-array-factory.js +++ b/lib/cascading-config-array-factory.js @@ -61,8 +61,10 @@ const debug = debugOrig("eslintrc:cascading-config-array-factory"); * @property {Function} loadRules The function to use to load rules. * @property {Map} builtInRules The rules that are built in to ESLint. * @property {Object} [resolver=ModuleResolver] The module resolver object. - * @property {ConfigData} eslintAllConfig The config data to the definitions for eslint:all. - * @property {ConfigData} eslintRecommendedConfig The config data to the definitions for eslint:recommended. + * @property {string} eslintAllPath The path to the definitions for eslint:all. + * @property {Function} getEslintAllConfig Returns the config data for eslint:all. + * @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended. + * @property {Function} getEslintRecommendedConfig Returns the config data for eslint:recommended. */ /** @@ -82,8 +84,10 @@ const debug = debugOrig("eslintrc:cascading-config-array-factory"); * @property {Function} loadRules The function to use to load rules. * @property {Map} builtInRules The rules that are built in to ESLint. * @property {Object} [resolver=ModuleResolver] The module resolver object. - * @property {ConfigData} eslintAllConfig The config data to the definitions for eslint:all. - * @property {ConfigData} eslintRecommendedConfig The config data to the definitions for eslint:recommended. + * @property {string} eslintAllPath The path to the definitions for eslint:all. + * @property {Function} getEslintAllConfig Returns the config data for eslint:all. + * @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended. + * @property {Function} getEslintRecommendedConfig Returns the config data for eslint:recommended. */ /** @type {WeakMap} */ @@ -223,8 +227,10 @@ class CascadingConfigArrayFactory { builtInRules = new Map(), loadRules, resolver, - eslintRecommendedConfig, - eslintAllConfig + eslintRecommendedPath, + getEslintRecommendedConfig, + eslintAllPath, + getEslintAllConfig } = {}) { const configArrayFactory = new ConfigArrayFactory({ additionalPluginPool, @@ -232,8 +238,10 @@ class CascadingConfigArrayFactory { resolvePluginsRelativeTo, builtInRules, resolver, - eslintRecommendedConfig, - eslintAllConfig + eslintRecommendedPath, + getEslintRecommendedConfig, + eslintAllPath, + getEslintAllConfig }); internalSlotsMap.set(this, { @@ -521,4 +529,5 @@ class CascadingConfigArrayFactory { //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ + export { CascadingConfigArrayFactory }; diff --git a/lib/config-array-factory.js b/lib/config-array-factory.js index 1c8de773..e1a67961 100644 --- a/lib/config-array-factory.js +++ b/lib/config-array-factory.js @@ -90,8 +90,10 @@ const configFilenames = [ * @property {string} [resolvePluginsRelativeTo] A path to the directory that plugins should be resolved from. Defaults to `cwd`. * @property {Map} builtInRules The rules that are built in to ESLint. * @property {Object} [resolver=ModuleResolver] The module resolver object. - * @property {import("./shared/types").ConfigData} eslintAllConfig The config data to the definitions for eslint:all. - * @property {import("./shared/types").ConfigData} eslintRecommendedConfig The config data to the definitions for eslint:recommended. + * @property {string} eslintAllPath The path to the definitions for eslint:all. + * @property {Function} getEslintAllConfig Returns the config data for eslint:all. + * @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended. + * @property {Function} getEslintRecommendedConfig Returns the config data for eslint:recommended. */ /** @@ -101,8 +103,10 @@ const configFilenames = [ * @property {string | undefined} resolvePluginsRelativeTo An absolute path the the directory that plugins should be resolved from. * @property {Map} builtInRules The rules that are built in to ESLint. * @property {Object} [resolver=ModuleResolver] The module resolver object. - * @property {import("./shared/types").ConfigData} eslintAllConfig The config data to the definitions for eslint:all. - * @property {import("./shared/types").ConfigData} eslintRecommendedConfig The config data to the definitions for eslint:recommended. + * @property {string} eslintAllPath The path to the definitions for eslint:all. + * @property {Function} getEslintAllConfig Returns the config data for eslint:all. + * @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended. + * @property {Function} getEslintRecommendedConfig Returns the config data for eslint:recommended. */ /** @@ -428,8 +432,10 @@ class ConfigArrayFactory { resolvePluginsRelativeTo, builtInRules, resolver = ModuleResolver, - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintAllConfig, + eslintRecommendedPath, + getEslintRecommendedConfig } = {}) { internalSlotsMap.set(this, { additionalPluginPool, @@ -439,8 +445,10 @@ class ConfigArrayFactory { path.resolve(cwd, resolvePluginsRelativeTo), builtInRules, resolver, - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintAllConfig, + eslintRecommendedPath, + getEslintRecommendedConfig }); } @@ -798,18 +806,35 @@ class ConfigArrayFactory { * @private */ _loadExtendedBuiltInConfig(extendName, ctx) { - const { eslintAllConfig, eslintRecommendedConfig } = internalSlotsMap.get(this); + const { + eslintAllPath, + getEslintAllConfig, + eslintRecommendedPath, + getEslintRecommendedConfig + } = internalSlotsMap.get(this); if (extendName === "eslint:recommended") { - return this._normalizeConfigData(eslintRecommendedConfig, { + const name = `${ctx.name} » ${extendName}`; + + if (getEslintRecommendedConfig) { + return this._normalizeConfigData(getEslintRecommendedConfig(), { ...ctx, name }); + } + return this._loadConfigData({ ...ctx, - name: `${ctx.name} » ${extendName}` + name, + filePath: eslintRecommendedPath }); } if (extendName === "eslint:all") { - return this._normalizeConfigData(eslintAllConfig, { + const name = `${ctx.name} » ${extendName}`; + + if (getEslintAllConfig) { + return this._normalizeConfigData(getEslintAllConfig(), { ...ctx, name }); + } + return this._loadConfigData({ ...ctx, - name: `${ctx.name} » ${extendName}` + name, + filePath: eslintAllPath }); } diff --git a/lib/flat-compat.js b/lib/flat-compat.js index f043741f..8df15a53 100644 --- a/lib/flat-compat.js +++ b/lib/flat-compat.js @@ -11,8 +11,6 @@ import createDebug from "debug"; import path from "path"; import environments from "../conf/environments.js"; -import eslintAllConfig from "../conf/eslint-all.cjs"; -import eslintRecommendedConfig from "../conf/eslint-recommended.cjs"; import { ConfigArrayFactory } from "./config-array-factory.js"; //----------------------------------------------------------------------------- @@ -224,8 +222,8 @@ class FlatCompat { this[cafactory] = new ConfigArrayFactory({ cwd: baseDirectory, resolvePluginsRelativeTo, - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig: () => ({ settings: { "eslint:all": true } }), + getEslintRecommendedConfig: () => ({ settings: { "eslint:recommended": true } }) }); } diff --git a/package.json b/package.json index 39177a36..a8d914fa 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,6 @@ }, "homepage": "https://github.com/eslint/eslintrc#readme", "devDependencies": { - "@rollup/plugin-commonjs": "^21.0.1", "c8": "^7.7.3", "chai": "^4.3.4", "eslint": "^7.31.0", diff --git a/rollup.config.js b/rollup.config.js index dee130f0..3ada0c1c 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,5 +1,3 @@ -import commonjs from "@rollup/plugin-commonjs"; - export default [ { input: "./lib/index.js", @@ -14,8 +12,7 @@ export default [ file: "dist/eslintrc.cjs", sourcemap: true, freeze: false - }, - plugins: [commonjs()] + } }, { input: "./lib/index-universal.js", @@ -30,7 +27,6 @@ export default [ file: "dist/eslintrc-universal.cjs", sourcemap: true, freeze: false - }, - plugins: [commonjs()] + } } ]; diff --git a/tests/lib/cascading-config-array-factory.js b/tests/lib/cascading-config-array-factory.js index 593fa66b..74b3aad4 100644 --- a/tests/lib/cascading-config-array-factory.js +++ b/tests/lib/cascading-config-array-factory.js @@ -18,8 +18,6 @@ import { fileURLToPath } from "url"; import { Legacy } from "../../lib/index.js"; import { createCustomTeardown } from "../_utils/index.js"; -import eslintAllConfig from "../fixtures/eslint-all.cjs"; -import eslintRecommendedConfig from "../fixtures/eslint-recommended.cjs"; const dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -40,6 +38,25 @@ const cwdIgnorePatterns = new ConfigArrayFactory() .ignorePattern .patterns; +const eslintAllPath = path.resolve(dirname, "../fixtures/eslint-all.cjs"); +const eslintRecommendedPath = path.resolve(dirname, "../fixtures/eslint-recommended.cjs"); + +/** + * Return config data for built-in eslint:all. + * @returns {ConfigData} Config data + */ +function getEslintAllConfig() { + return import("../fixtures/eslint-all.cjs"); +} + +/** + * Return config data for built-in eslint:recommended. + * @returns {ConfigData} Config data + */ +function getEslintRecommendedConfig() { + return import("../fixtures/eslint-recommended.cjs"); +} + //----------------------------------------------------------------------------- // Tests //----------------------------------------------------------------------------- @@ -656,8 +673,8 @@ describe("CascadingConfigArrayFactory", () => { cwd: fixtureDir, baseConfig: customBaseConfig, useEslintrc: false, - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); const config = getConfig(factory); @@ -676,8 +693,8 @@ describe("CascadingConfigArrayFactory", () => { // TODO: Tests should not rely on project files!!! it("should return the project config when called in current working directory", () => { const factory = new CascadingConfigArrayFactory({ - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); const actual = getConfig(factory); @@ -688,8 +705,8 @@ describe("CascadingConfigArrayFactory", () => { const firstpath = path.resolve(dirname, "../fixtures/configurations/single-quotes/subdir/.eslintrc"); const secondpath = path.resolve(dirname, "../fixtures/configurations/single-quotes/.eslintrc"); const factory = new CascadingConfigArrayFactory({ - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); let config; @@ -702,8 +719,8 @@ describe("CascadingConfigArrayFactory", () => { it("should throw error when a configuration file doesn't exist", () => { const configPath = path.resolve(dirname, "../fixtures/configurations/.eslintrc"); const factory = new CascadingConfigArrayFactory({ - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); sinon.stub(fs, "readFileSync").throws(new Error()); @@ -717,8 +734,8 @@ describe("CascadingConfigArrayFactory", () => { it("should throw error when a configuration file is not require-able", () => { const configPath = ".eslintrc"; const factory = new CascadingConfigArrayFactory({ - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); sinon.stub(fs, "readFileSync").throws(new Error()); @@ -734,8 +751,8 @@ describe("CascadingConfigArrayFactory", () => { const configArrayFactory = new ConfigArrayFactory(); const factory = new CascadingConfigArrayFactory({ configArrayFactory, - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); sinon.spy(configArrayFactory, "loadInDirectory"); @@ -755,8 +772,8 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath, useEslintrc: false, - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); const config = getConfig(factory); const { semi, strict } = config.rules; @@ -771,8 +788,8 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath, useEslintrc: false, - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); const config = getConfig(factory); const { "no-alert": noAlert, "no-undef": noUndef } = config.rules; @@ -784,8 +801,8 @@ describe("CascadingConfigArrayFactory", () => { it("should contain the correct value for parser when a custom parser is specified", () => { const configPath = path.resolve(dirname, "../fixtures/configurations/parser/.eslintrc.json"); const factory = new CascadingConfigArrayFactory({ - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); const config = getConfig(factory, configPath); @@ -799,8 +816,8 @@ describe("CascadingConfigArrayFactory", () => { it("should correctly merge environment settings", () => { const factory = new CascadingConfigArrayFactory({ useEslintrc: true, - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); const file = getFixturePath("envs", "sub", "foo.js"); const expected = { @@ -820,8 +837,8 @@ describe("CascadingConfigArrayFactory", () => { it("should return a blank config when using no .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ useEslintrc: false, - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); const file = getFixturePath("broken", "console-wrong-quotes.js"); const expected = { @@ -839,8 +856,8 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ baseConfig: false, useEslintrc: false, - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); const file = getFixturePath("broken", "console-wrong-quotes.js"); const expected = { @@ -858,8 +875,8 @@ describe("CascadingConfigArrayFactory", () => { it("should return an empty config when not using .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ useEslintrc: false, - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); const file = getFixturePath("broken", "console-wrong-quotes.js"); const actual = getConfig(factory, file); @@ -878,8 +895,8 @@ describe("CascadingConfigArrayFactory", () => { } }, useEslintrc: false, - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); const file = getFixturePath("broken", "console-wrong-quotes.js"); const expected = { @@ -909,8 +926,8 @@ describe("CascadingConfigArrayFactory", () => { }, cwd: getFixturePath("plugins"), useEslintrc: false, - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); const file = getFixturePath("broken", "plugins", "console-wrong-quotes.js"); const expected = { @@ -930,8 +947,8 @@ describe("CascadingConfigArrayFactory", () => { // Project configuration - second level .eslintrc it("should merge configs when local .eslintrc overrides parent .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); const file = getFixturePath("broken", "subbroken", "console-wrong-quotes.js"); const expected = { @@ -952,8 +969,8 @@ describe("CascadingConfigArrayFactory", () => { // Project configuration - third level .eslintrc it("should merge configs when local .eslintrc overrides parent and grandparent .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); const file = getFixturePath("broken", "subbroken", "subsubbroken", "console-wrong-quotes.js"); const expected = { @@ -974,8 +991,8 @@ describe("CascadingConfigArrayFactory", () => { // Project configuration - root set in second level .eslintrc it("should not return or traverse configurations in parents of config with root:true", () => { const factory = new CascadingConfigArrayFactory({ - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); const file = getFixturePath("root-true", "parent", "root", "wrong-semi.js"); const expected = { @@ -993,8 +1010,8 @@ describe("CascadingConfigArrayFactory", () => { it("should return project config when called with a relative path from a subdir", () => { const factory = new CascadingConfigArrayFactory({ cwd: getFixturePath("root-true", "parent", "root", "subdir"), - eslintRecommendedConfig, - eslintAllConfig + getEslintAllConfig, + eslintRecommendedPath }); const dir = "."; const expected = { @@ -1011,8 +1028,8 @@ describe("CascadingConfigArrayFactory", () => { it("should merge command line config when config file adds to local .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath: getFixturePath("broken", "add-conf.yaml"), - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); const file = getFixturePath("broken", "console-wrong-quotes.js"); const expected = { @@ -1034,8 +1051,8 @@ describe("CascadingConfigArrayFactory", () => { it("should merge command line config when config file overrides local .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath: getFixturePath("broken", "override-conf.yaml"), - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); const file = getFixturePath("broken", "console-wrong-quotes.js"); const expected = { @@ -1056,8 +1073,8 @@ describe("CascadingConfigArrayFactory", () => { it("should merge command line config when config file adds to local and parent .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath: getFixturePath("broken", "add-conf.yaml"), - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); const file = getFixturePath("broken", "subbroken", "console-wrong-quotes.js"); const expected = { @@ -1080,8 +1097,8 @@ describe("CascadingConfigArrayFactory", () => { it("should merge command line config when config file overrides local and parent .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath: getFixturePath("broken", "override-conf.yaml"), - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); const file = getFixturePath("broken", "subbroken", "console-wrong-quotes.js"); const expected = { @@ -1108,8 +1125,8 @@ describe("CascadingConfigArrayFactory", () => { } }, specificConfigPath: getFixturePath("broken", "override-conf.yaml"), - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); const file = getFixturePath("broken", "console-wrong-quotes.js"); const expected = { @@ -1134,8 +1151,8 @@ describe("CascadingConfigArrayFactory", () => { }, cwd: getFixturePath("plugins"), resolvePluginsRelativeTo: getFixturePath("plugins"), - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); const file = getFixturePath("broken", "plugins", "console-wrong-quotes.js"); const expected = { @@ -1158,8 +1175,8 @@ describe("CascadingConfigArrayFactory", () => { it("should merge multiple different config file formats", () => { const factory = new CascadingConfigArrayFactory({ - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); const file = getFixturePath("fileexts/subdir/subsubdir/foo.js"); const expected = { @@ -1183,8 +1200,8 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath: configPath, useEslintrc: false, - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); const expected = { globals: { @@ -1202,8 +1219,8 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath: configPath, useEslintrc: false, - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); const config = getConfig(factory, configPath); @@ -1214,8 +1231,8 @@ describe("CascadingConfigArrayFactory", () => { const configPath = path.resolve(dirname, "../fixtures/configurations/env-node.json"); const factory = new CascadingConfigArrayFactory({ specificConfigPath: configPath, - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); getConfig(factory, path.resolve(dirname, "../fixtures/configurations/empty/empty.json")); @@ -1229,8 +1246,8 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ useEslintrc: false, specificConfigPath: configPath, - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); getConfig(factory, configPath); @@ -1243,8 +1260,8 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ useEslintrc: false, specificConfigPath: configPath, - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); const expected = { rules: { "no-empty": [1], "comma-dangle": [2], "no-console": [2] }, @@ -1259,8 +1276,8 @@ describe("CascadingConfigArrayFactory", () => { describe("with env in a child configuration file", () => { it("should not overwrite parserOptions of the parent with env of the child", () => { const factory = new CascadingConfigArrayFactory({ - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); const targetPath = getFixturePath("overwrite-ecmaFeatures", "child", "foo.js"); const expected = { @@ -1305,8 +1322,8 @@ describe("CascadingConfigArrayFactory", () => { const filePath = getFakeFixturePath("personal-config", "project-without-config", "foo.js"); const factory = new CascadingConfigArrayFactory({ cwd: projectPath, - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); mockOsHomedir(homePath); @@ -1327,8 +1344,8 @@ describe("CascadingConfigArrayFactory", () => { const filePath = getFakeFixturePath("personal-config", "home-folder", "project", "foo.js"); const factory = new CascadingConfigArrayFactory({ cwd: projectPath, - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); mockOsHomedir(homePath); @@ -1351,8 +1368,8 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ cwd: projectPath, specificConfigPath: configPath, - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); mockOsHomedir(homePath); @@ -1372,8 +1389,8 @@ describe("CascadingConfigArrayFactory", () => { const filePath = getFakeFixturePath("personal-config", "project-with-config", "subfolder", "foo.js"); const factory = new CascadingConfigArrayFactory({ cwd: projectPath, - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); mockOsHomedir(projectPath); @@ -1420,8 +1437,8 @@ describe("CascadingConfigArrayFactory", () => { const filePath = getFakeFixturePath("personal-config", "project-without-config", "foo.js"); const factory = new CascadingConfigArrayFactory({ cwd: projectPath, - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); mockOsHomedir(homePath); @@ -1437,8 +1454,8 @@ describe("CascadingConfigArrayFactory", () => { const filePath = getFakeFixturePath("personal-config", "project-without-config", "foo.js"); const factory = new CascadingConfigArrayFactory({ cwd: projectPath, - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); mockOsHomedir(homePath); @@ -1455,8 +1472,8 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ cwd: projectPath, useEslintrc: false, - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); mockOsHomedir(homePath); @@ -1473,8 +1490,8 @@ describe("CascadingConfigArrayFactory", () => { rules: { quotes: [2, "single"] } }, cwd: projectPath, - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); mockOsHomedir(homePath); @@ -1489,8 +1506,8 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ baseConfig: {}, cwd: projectPath, - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); mockOsHomedir(homePath); @@ -1526,8 +1543,8 @@ describe("CascadingConfigArrayFactory", () => { it("should merge override config when the pattern matches the file name", () => { const factory = new CascadingConfigArrayFactory({ cwd: getPath(), - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); const targetPath = getFakeFixturePath("overrides", "foo.js"); const expected = { @@ -1546,8 +1563,8 @@ describe("CascadingConfigArrayFactory", () => { it("should merge override config when the pattern matches the file path relative to the config file", () => { const factory = new CascadingConfigArrayFactory({ cwd: getPath(), - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); const targetPath = getFakeFixturePath("overrides", "child", "child-one.js"); const expected = { @@ -1578,8 +1595,8 @@ describe("CascadingConfigArrayFactory", () => { }] }, useEslintrc: false, - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }), /Invalid override pattern/u); }); @@ -1596,16 +1613,16 @@ describe("CascadingConfigArrayFactory", () => { }] }, useEslintrc: false, - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }), /Invalid override pattern/u); }); it("should merge all local configs (override and non-override) before non-local configs", () => { const factory = new CascadingConfigArrayFactory({ cwd: getPath(), - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); const targetPath = getFakeFixturePath("overrides", "two", "child-two.js"); const expected = { @@ -1637,8 +1654,8 @@ describe("CascadingConfigArrayFactory", () => { ] }, useEslintrc: false, - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); const expected = { rules: { @@ -1663,8 +1680,8 @@ describe("CascadingConfigArrayFactory", () => { }] }, useEslintrc: false, - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); const expected = { rules: { @@ -1689,8 +1706,8 @@ describe("CascadingConfigArrayFactory", () => { }] }, useEslintrc: false, - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); const expected = { rules: { @@ -1716,8 +1733,8 @@ describe("CascadingConfigArrayFactory", () => { }] }, useEslintrc: false, - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); const expected = { rules: {} @@ -1741,8 +1758,8 @@ describe("CascadingConfigArrayFactory", () => { }] }, useEslintrc: false, - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); const expected = { rules: { @@ -1777,8 +1794,8 @@ describe("CascadingConfigArrayFactory", () => { ] }, useEslintrc: false, - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); const expected = { rules: { @@ -1813,8 +1830,8 @@ describe("CascadingConfigArrayFactory", () => { beforeEach(() => { factory = new CascadingConfigArrayFactory({ cwd, - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); warning = null; process.on("warning", onWarning); @@ -1955,8 +1972,8 @@ describe("CascadingConfigArrayFactory", () => { cwd: getPath(), additionalPluginPool, cliConfig: { plugins: ["test"] }, - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); }); diff --git a/tests/lib/config-array-factory.js b/tests/lib/config-array-factory.js index 373be074..a0b7e0e2 100644 --- a/tests/lib/config-array-factory.js +++ b/tests/lib/config-array-factory.js @@ -13,16 +13,18 @@ import { createRequire } from "module"; import path from "path"; import sinon from "sinon"; import systemTempDir from "temp-dir"; -import { fileURLToPath } from "url"; +import { + fileURLToPath, + pathToFileURL +} from "url"; import { Legacy } from "../../lib/index.js"; import { createCustomTeardown } from "../_utils/index.js"; -import eslintAllConfig from "../fixtures/eslint-all.cjs"; -import eslintRecommendedConfig from "../fixtures/eslint-recommended.cjs"; const require = createRequire(import.meta.url); const fileName = fileURLToPath(import.meta.url); +const dirname = path.dirname(fileName); const { spy } = sinon; const { @@ -36,8 +38,26 @@ const { // Helpers //----------------------------------------------------------------------------- +const eslintAllPath = path.resolve(dirname, "../fixtures/eslint-all.cjs"); +const eslintRecommendedPath = path.resolve(dirname, "../fixtures/eslint-recommended.cjs"); const tempDir = path.join(systemTempDir, "eslintrc/config-array-factory"); +/** + * Return config data for built-in eslint:all. + * @returns {ConfigData} Config data + */ +function getEslintAllConfig() { + return import("../fixtures/eslint-all.cjs"); +} + +/** + * Return config data for built-in eslint:recommended. + * @returns {ConfigData} Config data + */ +function getEslintRecommendedConfig() { + return import("../fixtures/eslint-recommended.cjs"); +} + /** * Assert a config array element. * @param {Object} actual The actual value. @@ -953,8 +973,8 @@ describe("ConfigArrayFactory", () => { factory = new ConfigArrayFactory({ cwd: getPath(), - eslintAllConfig, - eslintRecommendedConfig + getEslintAllConfig, + eslintRecommendedPath }); }); @@ -1023,7 +1043,8 @@ describe("ConfigArrayFactory", () => { it("should have the config data of 'eslint:all' at the first element.", async () => { assertConfigArrayElement(configArray[0], { name: ".eslintrc » eslint:all", - ...eslintAllConfig + filePath: eslintAllPath, + ...(await import(pathToFileURL(eslintAllPath))).default }); }); @@ -1052,7 +1073,8 @@ describe("ConfigArrayFactory", () => { it("should have the config data of 'eslint:recommended' at the first element.", async () => { assertConfigArrayElement(configArray[0], { name: ".eslintrc » eslint:recommended", - ...eslintRecommendedConfig + filePath: eslintRecommendedPath, + ...(await import(pathToFileURL(eslintRecommendedPath))).default }); }); @@ -1592,8 +1614,8 @@ describe("ConfigArrayFactory", () => { await prepare(); factory = new ConfigArrayFactory({ cwd: getPath(), - eslintAllConfig, - eslintRecommendedConfig + eslintAllPath, + getEslintRecommendedConfig }); }); @@ -1807,7 +1829,7 @@ describe("ConfigArrayFactory", () => { let cleanup; beforeEach(() => { - cleanup = () => { }; + cleanup = () => {}; }); afterEach(() => cleanup()); @@ -2506,18 +2528,7 @@ env: try { load(factory, "invalid/invalid-top-level-property.yml"); } catch (err) { - - /** - * Received error message is: - * - * ``` - * ESLint configuration: { - * "invalidProperty": 3 - * } in invalid/invalid-top-level-property.yml is invalid: - * - Unexpected top-level property "invalidProperty". - * ``` - */ - assert.include(err.message, `${`invalid${path.sep}invalid-top-level-property.yml`} is invalid`); + assert.include(err.message, `ESLint configuration in ${`invalid${path.sep}invalid-top-level-property.yml`} is invalid`); return; } assert.fail(); From 646b3a8e5028ab286994b22226443fd01c58b6b8 Mon Sep 17 00:00:00 2001 From: Zhao DAI Date: Sun, 13 Feb 2022 13:37:31 +0000 Subject: [PATCH 3/3] fix: Avoid dirname for built-in configs. Load eslint:recommended and eslint:all configs via import instead file paths. Fixes: https://github.com/eslint/eslint/issues/15575 --- lib/cascading-config-array-factory.js | 23 +++- lib/config-array-factory.js | 50 ++++++-- lib/flat-compat.js | 11 +- tests/lib/cascading-config-array-factory.js | 132 +++++++++++--------- tests/lib/config-array-factory.js | 32 ++++- 5 files changed, 159 insertions(+), 89 deletions(-) diff --git a/lib/cascading-config-array-factory.js b/lib/cascading-config-array-factory.js index 553ca0a9..4b575c2d 100644 --- a/lib/cascading-config-array-factory.js +++ b/lib/cascading-config-array-factory.js @@ -22,13 +22,18 @@ // Requirements //------------------------------------------------------------------------------ +import debugOrig from "debug"; import os from "os"; import path from "path"; + +import { ConfigArrayFactory } from "./config-array-factory.js"; +import { + ConfigArray, + ConfigDependency, + IgnorePattern +} from "./config-array/index.js"; import ConfigValidator from "./shared/config-validator.js"; import { emitDeprecationWarning } from "./shared/deprecation-warnings.js"; -import { ConfigArrayFactory } from "./config-array-factory.js"; -import { ConfigArray, ConfigDependency, IgnorePattern } from "./config-array/index.js"; -import debugOrig from "debug"; const debug = debugOrig("eslintrc:cascading-config-array-factory"); @@ -57,7 +62,9 @@ const debug = debugOrig("eslintrc:cascading-config-array-factory"); * @property {Map} builtInRules The rules that are built in to ESLint. * @property {Object} [resolver=ModuleResolver] The module resolver object. * @property {string} eslintAllPath The path to the definitions for eslint:all. + * @property {Function} getEslintAllConfig Returns the config data for eslint:all. * @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended. + * @property {Function} getEslintRecommendedConfig Returns the config data for eslint:recommended. */ /** @@ -78,7 +85,9 @@ const debug = debugOrig("eslintrc:cascading-config-array-factory"); * @property {Map} builtInRules The rules that are built in to ESLint. * @property {Object} [resolver=ModuleResolver] The module resolver object. * @property {string} eslintAllPath The path to the definitions for eslint:all. + * @property {Function} getEslintAllConfig Returns the config data for eslint:all. * @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended. + * @property {Function} getEslintRecommendedConfig Returns the config data for eslint:recommended. */ /** @type {WeakMap} */ @@ -219,7 +228,9 @@ class CascadingConfigArrayFactory { loadRules, resolver, eslintRecommendedPath, - eslintAllPath + getEslintRecommendedConfig, + eslintAllPath, + getEslintAllConfig } = {}) { const configArrayFactory = new ConfigArrayFactory({ additionalPluginPool, @@ -228,7 +239,9 @@ class CascadingConfigArrayFactory { builtInRules, resolver, eslintRecommendedPath, - eslintAllPath + getEslintRecommendedConfig, + eslintAllPath, + getEslintAllConfig }); internalSlotsMap.set(this, { diff --git a/lib/config-array-factory.js b/lib/config-array-factory.js index b571e2f7..e1a67961 100644 --- a/lib/config-array-factory.js +++ b/lib/config-array-factory.js @@ -38,22 +38,23 @@ // Requirements //------------------------------------------------------------------------------ +import debugOrig from "debug"; import fs from "fs"; -import path from "path"; import importFresh from "import-fresh"; +import { createRequire } from "module"; +import path from "path"; import stripComments from "strip-json-comments"; -import ConfigValidator from "./shared/config-validator.js"; -import * as naming from "./shared/naming.js"; -import * as ModuleResolver from "./shared/relative-module-resolver.js"; + import { ConfigArray, ConfigDependency, IgnorePattern, OverrideTester } from "./config-array/index.js"; -import debugOrig from "debug"; +import ConfigValidator from "./shared/config-validator.js"; +import * as naming from "./shared/naming.js"; +import * as ModuleResolver from "./shared/relative-module-resolver.js"; -import { createRequire } from "module"; const require = createRequire(import.meta.url); const debug = debugOrig("eslintrc:config-array-factory"); @@ -90,7 +91,9 @@ const configFilenames = [ * @property {Map} builtInRules The rules that are built in to ESLint. * @property {Object} [resolver=ModuleResolver] The module resolver object. * @property {string} eslintAllPath The path to the definitions for eslint:all. + * @property {Function} getEslintAllConfig Returns the config data for eslint:all. * @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended. + * @property {Function} getEslintRecommendedConfig Returns the config data for eslint:recommended. */ /** @@ -101,7 +104,9 @@ const configFilenames = [ * @property {Map} builtInRules The rules that are built in to ESLint. * @property {Object} [resolver=ModuleResolver] The module resolver object. * @property {string} eslintAllPath The path to the definitions for eslint:all. + * @property {Function} getEslintAllConfig Returns the config data for eslint:all. * @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended. + * @property {Function} getEslintRecommendedConfig Returns the config data for eslint:recommended. */ /** @@ -428,7 +433,9 @@ class ConfigArrayFactory { builtInRules, resolver = ModuleResolver, eslintAllPath, - eslintRecommendedPath + getEslintAllConfig, + eslintRecommendedPath, + getEslintRecommendedConfig } = {}) { internalSlotsMap.set(this, { additionalPluginPool, @@ -439,7 +446,9 @@ class ConfigArrayFactory { builtInRules, resolver, eslintAllPath, - eslintRecommendedPath + getEslintAllConfig, + eslintRecommendedPath, + getEslintRecommendedConfig }); } @@ -797,20 +806,35 @@ class ConfigArrayFactory { * @private */ _loadExtendedBuiltInConfig(extendName, ctx) { - const { eslintAllPath, eslintRecommendedPath } = internalSlotsMap.get(this); + const { + eslintAllPath, + getEslintAllConfig, + eslintRecommendedPath, + getEslintRecommendedConfig + } = internalSlotsMap.get(this); if (extendName === "eslint:recommended") { + const name = `${ctx.name} » ${extendName}`; + + if (getEslintRecommendedConfig) { + return this._normalizeConfigData(getEslintRecommendedConfig(), { ...ctx, name }); + } return this._loadConfigData({ ...ctx, - filePath: eslintRecommendedPath, - name: `${ctx.name} » ${extendName}` + name, + filePath: eslintRecommendedPath }); } if (extendName === "eslint:all") { + const name = `${ctx.name} » ${extendName}`; + + if (getEslintAllConfig) { + return this._normalizeConfigData(getEslintAllConfig(), { ...ctx, name }); + } return this._loadConfigData({ ...ctx, - filePath: eslintAllPath, - name: `${ctx.name} » ${extendName}` + name, + filePath: eslintAllPath }); } diff --git a/lib/flat-compat.js b/lib/flat-compat.js index 7fa111d3..8df15a53 100644 --- a/lib/flat-compat.js +++ b/lib/flat-compat.js @@ -7,14 +7,11 @@ // Requirements //----------------------------------------------------------------------------- -import path from "path"; -import { fileURLToPath } from "url"; import createDebug from "debug"; +import path from "path"; -import { ConfigArrayFactory } from "./config-array-factory.js"; import environments from "../conf/environments.js"; - -const dirname = path.dirname(fileURLToPath(import.meta.url)); +import { ConfigArrayFactory } from "./config-array-factory.js"; //----------------------------------------------------------------------------- // Helpers @@ -225,8 +222,8 @@ class FlatCompat { this[cafactory] = new ConfigArrayFactory({ cwd: baseDirectory, resolvePluginsRelativeTo, - eslintAllPath: path.resolve(dirname, "../conf/eslint-all.cjs"), - eslintRecommendedPath: path.resolve(dirname, "../conf/eslint-recommended.cjs") + getEslintAllConfig: () => ({ settings: { "eslint:all": true } }), + getEslintRecommendedConfig: () => ({ settings: { "eslint:recommended": true } }) }); } diff --git a/tests/lib/cascading-config-array-factory.js b/tests/lib/cascading-config-array-factory.js index 64b70395..74b3aad4 100644 --- a/tests/lib/cascading-config-array-factory.js +++ b/tests/lib/cascading-config-array-factory.js @@ -7,14 +7,14 @@ // Requirements //----------------------------------------------------------------------------- +import { assert } from "chai"; import fs from "fs"; -import path from "path"; -import { fileURLToPath } from "url"; import os from "os"; -import { assert } from "chai"; +import path from "path"; import sh from "shelljs"; import sinon from "sinon"; import systemTempDir from "temp-dir"; +import { fileURLToPath } from "url"; import { Legacy } from "../../lib/index.js"; import { createCustomTeardown } from "../_utils/index.js"; @@ -41,6 +41,22 @@ const cwdIgnorePatterns = new ConfigArrayFactory() const eslintAllPath = path.resolve(dirname, "../fixtures/eslint-all.cjs"); const eslintRecommendedPath = path.resolve(dirname, "../fixtures/eslint-recommended.cjs"); +/** + * Return config data for built-in eslint:all. + * @returns {ConfigData} Config data + */ +function getEslintAllConfig() { + return import("../fixtures/eslint-all.cjs"); +} + +/** + * Return config data for built-in eslint:recommended. + * @returns {ConfigData} Config data + */ +function getEslintRecommendedConfig() { + return import("../fixtures/eslint-recommended.cjs"); +} + //----------------------------------------------------------------------------- // Tests //----------------------------------------------------------------------------- @@ -657,7 +673,7 @@ describe("CascadingConfigArrayFactory", () => { cwd: fixtureDir, baseConfig: customBaseConfig, useEslintrc: false, - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); const config = getConfig(factory); @@ -678,7 +694,7 @@ describe("CascadingConfigArrayFactory", () => { it("should return the project config when called in current working directory", () => { const factory = new CascadingConfigArrayFactory({ eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); const actual = getConfig(factory); @@ -689,7 +705,7 @@ describe("CascadingConfigArrayFactory", () => { const firstpath = path.resolve(dirname, "../fixtures/configurations/single-quotes/subdir/.eslintrc"); const secondpath = path.resolve(dirname, "../fixtures/configurations/single-quotes/.eslintrc"); const factory = new CascadingConfigArrayFactory({ - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); let config; @@ -704,7 +720,7 @@ describe("CascadingConfigArrayFactory", () => { const configPath = path.resolve(dirname, "../fixtures/configurations/.eslintrc"); const factory = new CascadingConfigArrayFactory({ eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); sinon.stub(fs, "readFileSync").throws(new Error()); @@ -718,7 +734,7 @@ describe("CascadingConfigArrayFactory", () => { it("should throw error when a configuration file is not require-able", () => { const configPath = ".eslintrc"; const factory = new CascadingConfigArrayFactory({ - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); @@ -736,7 +752,7 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ configArrayFactory, eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); sinon.spy(configArrayFactory, "loadInDirectory"); @@ -756,7 +772,7 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath, useEslintrc: false, - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); const config = getConfig(factory); @@ -773,7 +789,7 @@ describe("CascadingConfigArrayFactory", () => { specificConfigPath, useEslintrc: false, eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); const config = getConfig(factory); const { "no-alert": noAlert, "no-undef": noUndef } = config.rules; @@ -785,7 +801,7 @@ describe("CascadingConfigArrayFactory", () => { it("should contain the correct value for parser when a custom parser is specified", () => { const configPath = path.resolve(dirname, "../fixtures/configurations/parser/.eslintrc.json"); const factory = new CascadingConfigArrayFactory({ - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); const config = getConfig(factory, configPath); @@ -801,7 +817,7 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ useEslintrc: true, eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); const file = getFixturePath("envs", "sub", "foo.js"); const expected = { @@ -821,7 +837,7 @@ describe("CascadingConfigArrayFactory", () => { it("should return a blank config when using no .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ useEslintrc: false, - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); const file = getFixturePath("broken", "console-wrong-quotes.js"); @@ -841,7 +857,7 @@ describe("CascadingConfigArrayFactory", () => { baseConfig: false, useEslintrc: false, eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); const file = getFixturePath("broken", "console-wrong-quotes.js"); const expected = { @@ -859,7 +875,7 @@ describe("CascadingConfigArrayFactory", () => { it("should return an empty config when not using .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ useEslintrc: false, - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); const file = getFixturePath("broken", "console-wrong-quotes.js"); @@ -880,7 +896,7 @@ describe("CascadingConfigArrayFactory", () => { }, useEslintrc: false, eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); const file = getFixturePath("broken", "console-wrong-quotes.js"); const expected = { @@ -910,7 +926,7 @@ describe("CascadingConfigArrayFactory", () => { }, cwd: getFixturePath("plugins"), useEslintrc: false, - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); const file = getFixturePath("broken", "plugins", "console-wrong-quotes.js"); @@ -932,7 +948,7 @@ describe("CascadingConfigArrayFactory", () => { it("should merge configs when local .eslintrc overrides parent .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); const file = getFixturePath("broken", "subbroken", "console-wrong-quotes.js"); const expected = { @@ -953,7 +969,7 @@ describe("CascadingConfigArrayFactory", () => { // Project configuration - third level .eslintrc it("should merge configs when local .eslintrc overrides parent and grandparent .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); const file = getFixturePath("broken", "subbroken", "subsubbroken", "console-wrong-quotes.js"); @@ -976,7 +992,7 @@ describe("CascadingConfigArrayFactory", () => { it("should not return or traverse configurations in parents of config with root:true", () => { const factory = new CascadingConfigArrayFactory({ eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); const file = getFixturePath("root-true", "parent", "root", "wrong-semi.js"); const expected = { @@ -994,8 +1010,8 @@ describe("CascadingConfigArrayFactory", () => { it("should return project config when called with a relative path from a subdir", () => { const factory = new CascadingConfigArrayFactory({ cwd: getFixturePath("root-true", "parent", "root", "subdir"), - eslintRecommendedPath, - eslintAllPath + getEslintAllConfig, + eslintRecommendedPath }); const dir = "."; const expected = { @@ -1013,7 +1029,7 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath: getFixturePath("broken", "add-conf.yaml"), eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); const file = getFixturePath("broken", "console-wrong-quotes.js"); const expected = { @@ -1035,7 +1051,7 @@ describe("CascadingConfigArrayFactory", () => { it("should merge command line config when config file overrides local .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath: getFixturePath("broken", "override-conf.yaml"), - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); const file = getFixturePath("broken", "console-wrong-quotes.js"); @@ -1058,7 +1074,7 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath: getFixturePath("broken", "add-conf.yaml"), eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); const file = getFixturePath("broken", "subbroken", "console-wrong-quotes.js"); const expected = { @@ -1081,7 +1097,7 @@ describe("CascadingConfigArrayFactory", () => { it("should merge command line config when config file overrides local and parent .eslintrc", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath: getFixturePath("broken", "override-conf.yaml"), - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); const file = getFixturePath("broken", "subbroken", "console-wrong-quotes.js"); @@ -1110,7 +1126,7 @@ describe("CascadingConfigArrayFactory", () => { }, specificConfigPath: getFixturePath("broken", "override-conf.yaml"), eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); const file = getFixturePath("broken", "console-wrong-quotes.js"); const expected = { @@ -1135,7 +1151,7 @@ describe("CascadingConfigArrayFactory", () => { }, cwd: getFixturePath("plugins"), resolvePluginsRelativeTo: getFixturePath("plugins"), - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); const file = getFixturePath("broken", "plugins", "console-wrong-quotes.js"); @@ -1160,7 +1176,7 @@ describe("CascadingConfigArrayFactory", () => { it("should merge multiple different config file formats", () => { const factory = new CascadingConfigArrayFactory({ eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); const file = getFixturePath("fileexts/subdir/subsubdir/foo.js"); const expected = { @@ -1184,7 +1200,7 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ specificConfigPath: configPath, useEslintrc: false, - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); const expected = { @@ -1204,7 +1220,7 @@ describe("CascadingConfigArrayFactory", () => { specificConfigPath: configPath, useEslintrc: false, eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); const config = getConfig(factory, configPath); @@ -1215,7 +1231,7 @@ describe("CascadingConfigArrayFactory", () => { const configPath = path.resolve(dirname, "../fixtures/configurations/env-node.json"); const factory = new CascadingConfigArrayFactory({ specificConfigPath: configPath, - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); @@ -1231,7 +1247,7 @@ describe("CascadingConfigArrayFactory", () => { useEslintrc: false, specificConfigPath: configPath, eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); getConfig(factory, configPath); @@ -1244,7 +1260,7 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ useEslintrc: false, specificConfigPath: configPath, - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); const expected = { @@ -1261,7 +1277,7 @@ describe("CascadingConfigArrayFactory", () => { it("should not overwrite parserOptions of the parent with env of the child", () => { const factory = new CascadingConfigArrayFactory({ eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); const targetPath = getFixturePath("overwrite-ecmaFeatures", "child", "foo.js"); const expected = { @@ -1306,7 +1322,7 @@ describe("CascadingConfigArrayFactory", () => { const filePath = getFakeFixturePath("personal-config", "project-without-config", "foo.js"); const factory = new CascadingConfigArrayFactory({ cwd: projectPath, - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); @@ -1329,7 +1345,7 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ cwd: projectPath, eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); mockOsHomedir(homePath); @@ -1352,7 +1368,7 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ cwd: projectPath, specificConfigPath: configPath, - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); @@ -1374,7 +1390,7 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ cwd: projectPath, eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); mockOsHomedir(projectPath); @@ -1421,7 +1437,7 @@ describe("CascadingConfigArrayFactory", () => { const filePath = getFakeFixturePath("personal-config", "project-without-config", "foo.js"); const factory = new CascadingConfigArrayFactory({ cwd: projectPath, - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); @@ -1439,7 +1455,7 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ cwd: projectPath, eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); mockOsHomedir(homePath); @@ -1456,7 +1472,7 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ cwd: projectPath, useEslintrc: false, - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); @@ -1475,7 +1491,7 @@ describe("CascadingConfigArrayFactory", () => { }, cwd: projectPath, eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); mockOsHomedir(homePath); @@ -1490,7 +1506,7 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ baseConfig: {}, cwd: projectPath, - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); @@ -1528,7 +1544,7 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ cwd: getPath(), eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); const targetPath = getFakeFixturePath("overrides", "foo.js"); const expected = { @@ -1547,7 +1563,7 @@ describe("CascadingConfigArrayFactory", () => { it("should merge override config when the pattern matches the file path relative to the config file", () => { const factory = new CascadingConfigArrayFactory({ cwd: getPath(), - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); const targetPath = getFakeFixturePath("overrides", "child", "child-one.js"); @@ -1580,7 +1596,7 @@ describe("CascadingConfigArrayFactory", () => { }, useEslintrc: false, eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }), /Invalid override pattern/u); }); @@ -1597,7 +1613,7 @@ describe("CascadingConfigArrayFactory", () => { }] }, useEslintrc: false, - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }), /Invalid override pattern/u); }); @@ -1606,7 +1622,7 @@ describe("CascadingConfigArrayFactory", () => { const factory = new CascadingConfigArrayFactory({ cwd: getPath(), eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); const targetPath = getFakeFixturePath("overrides", "two", "child-two.js"); const expected = { @@ -1638,7 +1654,7 @@ describe("CascadingConfigArrayFactory", () => { ] }, useEslintrc: false, - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); const expected = { @@ -1665,7 +1681,7 @@ describe("CascadingConfigArrayFactory", () => { }, useEslintrc: false, eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); const expected = { rules: { @@ -1690,7 +1706,7 @@ describe("CascadingConfigArrayFactory", () => { }] }, useEslintrc: false, - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); const expected = { @@ -1718,7 +1734,7 @@ describe("CascadingConfigArrayFactory", () => { }, useEslintrc: false, eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); const expected = { rules: {} @@ -1742,7 +1758,7 @@ describe("CascadingConfigArrayFactory", () => { }] }, useEslintrc: false, - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); const expected = { @@ -1779,7 +1795,7 @@ describe("CascadingConfigArrayFactory", () => { }, useEslintrc: false, eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); const expected = { rules: { @@ -1814,7 +1830,7 @@ describe("CascadingConfigArrayFactory", () => { beforeEach(() => { factory = new CascadingConfigArrayFactory({ cwd, - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); warning = null; @@ -1957,7 +1973,7 @@ describe("CascadingConfigArrayFactory", () => { additionalPluginPool, cliConfig: { plugins: ["test"] }, eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); }); diff --git a/tests/lib/config-array-factory.js b/tests/lib/config-array-factory.js index 805159fd..a0b7e0e2 100644 --- a/tests/lib/config-array-factory.js +++ b/tests/lib/config-array-factory.js @@ -7,15 +7,19 @@ // Requirements //----------------------------------------------------------------------------- -import path from "path"; -import { fileURLToPath, pathToFileURL } from "url"; +import { assert } from "chai"; import fs from "fs"; import { createRequire } from "module"; -import { assert } from "chai"; +import path from "path"; import sinon from "sinon"; +import systemTempDir from "temp-dir"; +import { + fileURLToPath, + pathToFileURL +} from "url"; + import { Legacy } from "../../lib/index.js"; import { createCustomTeardown } from "../_utils/index.js"; -import systemTempDir from "temp-dir"; const require = createRequire(import.meta.url); @@ -38,6 +42,22 @@ const eslintAllPath = path.resolve(dirname, "../fixtures/eslint-all.cjs"); const eslintRecommendedPath = path.resolve(dirname, "../fixtures/eslint-recommended.cjs"); const tempDir = path.join(systemTempDir, "eslintrc/config-array-factory"); +/** + * Return config data for built-in eslint:all. + * @returns {ConfigData} Config data + */ +function getEslintAllConfig() { + return import("../fixtures/eslint-all.cjs"); +} + +/** + * Return config data for built-in eslint:recommended. + * @returns {ConfigData} Config data + */ +function getEslintRecommendedConfig() { + return import("../fixtures/eslint-recommended.cjs"); +} + /** * Assert a config array element. * @param {Object} actual The actual value. @@ -953,7 +973,7 @@ describe("ConfigArrayFactory", () => { factory = new ConfigArrayFactory({ cwd: getPath(), - eslintAllPath, + getEslintAllConfig, eslintRecommendedPath }); }); @@ -1595,7 +1615,7 @@ describe("ConfigArrayFactory", () => { factory = new ConfigArrayFactory({ cwd: getPath(), eslintAllPath, - eslintRecommendedPath + getEslintRecommendedConfig }); });