From 9b1b3413baace7b366c65a6ad84b5ce12a9e3aac Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Sat, 28 Jan 2023 10:22:05 +0530 Subject: [PATCH 01/10] fix: correctly iterate files matched by glob patterns --- lib/cli-engine/file-enumerator.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/cli-engine/file-enumerator.js b/lib/cli-engine/file-enumerator.js index b65d0a20692..4797127cf37 100644 --- a/lib/cli-engine/file-enumerator.js +++ b/lib/cli-engine/file-enumerator.js @@ -349,7 +349,7 @@ class FileEnumerator { return this._iterateFilesWithFile(absolutePath); } if (globInputPaths && isGlobPattern(pattern)) { - return this._iterateFilesWithGlob(absolutePath, isDot); + return this._iterateFilesWithGlob(pattern, isDot); } return []; @@ -398,15 +398,17 @@ class FileEnumerator { _iterateFilesWithGlob(pattern, dotfiles) { debug(`Glob: ${pattern}`); - const directoryPath = path.resolve(getGlobParent(pattern)); - const globPart = pattern.slice(directoryPath.length + 1); + const { cwd } = internalSlotsMap.get(this); + const directoryPath = path.resolve(cwd, getGlobParent(pattern)); + const absolutePath = path.resolve(cwd, pattern); + const globPart = absolutePath.slice(directoryPath.length + 1); /* * recursive if there are `**` or path separators in the glob part. * Otherwise, patterns such as `src/*.js`, it doesn't need recursive. */ const recursive = /\*\*|\/|\\/u.test(globPart); - const selector = new Minimatch(pattern, minimatchOpts); + const selector = new Minimatch(absolutePath, minimatchOpts); debug(`recursive? ${recursive}`); From b4cf8b72e92be88efb22c10ea2f99ed08364d4bd Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Sat, 18 Feb 2023 15:37:12 +0530 Subject: [PATCH 02/10] test: add a test case for #14742 --- tests/lib/cli-engine/file-enumerator.js | 54 +++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/lib/cli-engine/file-enumerator.js b/tests/lib/cli-engine/file-enumerator.js index 2ccf15e73d1..c4ec90c49cf 100644 --- a/tests/lib/cli-engine/file-enumerator.js +++ b/tests/lib/cli-engine/file-enumerator.js @@ -182,6 +182,60 @@ describe("FileEnumerator", () => { }); }); + // https://github.com/eslint/eslint/issues/14742 + describe.only("with 5 directories ('{lib}', '{lib}/client', '{lib}/client/src', '{lib}/server', '{lib}/server/src') that contains two files '{lib}/client/src/one.js' and '{lib}/server/src/two.js'", () => { + const root = path.join("/Users/snitin315/Desktop/eslint/file-enumerator"); + const files = { + "{lib}/client/src/one.js": "console.log('one.js');", + "{lib}/server/src/two.js": "console.log('two.js');", + "{lib}/client/.eslintrc.json": JSON.stringify({ + rules: { + "no-console": "error" + }, + env: { + mocha: true + } + }), + "{lib}/server/.eslintrc.json": JSON.stringify({ + rules: { + "no-console": "off" + }, + env: { + mocha: true + } + }) + }; + const { prepare, cleanup, getPath } = createCustomTeardown({ + cwd: root, + files + }); + + /** @type {FileEnumerator} */ + let enumerator; + + beforeEach(async () => { + await prepare(); + enumerator = new FileEnumerator({ + cwd: path.resolve(getPath("{lib}/server")) + }); + }); + + afterEach(cleanup); + + describe("when running eslint in the server directory", () => { + it("should use the config '{lib}/server/.eslintrc.json' for '{lib}/server/src/two.js'.", () => { + const list = [ + ...enumerator.iterateFiles(["src/**/*.{js,json}"]) + ]; + + assert.strictEqual(list.length, 1); + assert.strictEqual(list[0].config.length, 2); + assert.strictEqual(list[0].config[0].name, "DefaultIgnorePattern"); + assert.strictEqual(list[0].config[1].filePath, getPath("{lib}/server/.eslintrc.json")); + }); + }); + }); + // This group moved from 'tests/lib/util/glob-utils.js' when refactoring to keep the cumulated test cases. describe("with 'tests/fixtures/glob-utils' files", () => { let fixtureDir; From 81009bbe5ee64b50fd9e1782b5a9cb2280cf5ce4 Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Sat, 18 Feb 2023 16:08:29 +0530 Subject: [PATCH 03/10] test: improve test case --- lib/cli-engine/file-enumerator.js | 15 +++++++++++++++ tests/lib/cli-engine/file-enumerator.js | 14 ++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/lib/cli-engine/file-enumerator.js b/lib/cli-engine/file-enumerator.js index 4797127cf37..2316a498dc4 100644 --- a/lib/cli-engine/file-enumerator.js +++ b/lib/cli-engine/file-enumerator.js @@ -287,6 +287,8 @@ class FileEnumerator { const set = new Set(); for (const pattern of patterns) { + + // console.log("🚀 ~ file: file-enumerator.js:290 ~ FileEnumerator ~ *iterateFiles ~ pattern", pattern) let foundRegardlessOfIgnored = false; let found = false; @@ -350,6 +352,8 @@ class FileEnumerator { } if (globInputPaths && isGlobPattern(pattern)) { return this._iterateFilesWithGlob(pattern, isDot); + + // return this._iterateFilesWithGlob(absolutePath, isDot); } return []; @@ -398,6 +402,10 @@ class FileEnumerator { _iterateFilesWithGlob(pattern, dotfiles) { debug(`Glob: ${pattern}`); + /* + * const directoryPath = path.resolve(getGlobParent(pattern)); + * const globPart = pattern.slice(directoryPath.length + 1); + */ const { cwd } = internalSlotsMap.get(this); const directoryPath = path.resolve(cwd, getGlobParent(pattern)); const absolutePath = path.resolve(cwd, pattern); @@ -410,6 +418,8 @@ class FileEnumerator { const recursive = /\*\*|\/|\\/u.test(globPart); const selector = new Minimatch(absolutePath, minimatchOpts); + // const selector = new Minimatch(pattern, minimatchOpts); + debug(`recursive? ${recursive}`); return this._iterateFilesRecursive( @@ -458,6 +468,11 @@ class FileEnumerator { { ignoreNotFoundError: true } ); } + + // console.log(options); + debug( + `Selector: ${filePath}, ${options.selector.match(filePath)}` + ); const matched = options.selector // Started with a glob pattern; choose by the pattern. diff --git a/tests/lib/cli-engine/file-enumerator.js b/tests/lib/cli-engine/file-enumerator.js index c4ec90c49cf..2f2b0abe578 100644 --- a/tests/lib/cli-engine/file-enumerator.js +++ b/tests/lib/cli-engine/file-enumerator.js @@ -13,6 +13,7 @@ const path = require("path"); const os = require("os"); const { assert } = require("chai"); const sh = require("shelljs"); +const sinon = require("sinon"); const { Legacy: { CascadingConfigArrayFactory @@ -224,14 +225,27 @@ describe("FileEnumerator", () => { describe("when running eslint in the server directory", () => { it("should use the config '{lib}/server/.eslintrc.json' for '{lib}/server/src/two.js'.", () => { + const spy = sinon.spy(fs, "readdirSync"); + const list = [ ...enumerator.iterateFiles(["src/**/*.{js,json}"]) ]; + // should enter the directory '{lib}/server/src' directly + assert.strictEqual(spy.getCall(0).firstArg, path.join(root, "{lib}/server/src")); assert.strictEqual(list.length, 1); assert.strictEqual(list[0].config.length, 2); assert.strictEqual(list[0].config[0].name, "DefaultIgnorePattern"); assert.strictEqual(list[0].config[1].filePath, getPath("{lib}/server/.eslintrc.json")); + assert.deepStrictEqual( + list.map(entry => entry.filePath), + [ + path.join(root, "{lib}/server/src/two.js") + ] + ); + + // destroy the spy + sinon.restore(); }); }); }); From 2843313c22581a780ebc670215a6f226edbb8b47 Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Sat, 18 Feb 2023 16:11:43 +0530 Subject: [PATCH 04/10] chore: remove .only --- tests/lib/cli-engine/file-enumerator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lib/cli-engine/file-enumerator.js b/tests/lib/cli-engine/file-enumerator.js index 2f2b0abe578..93655219ce8 100644 --- a/tests/lib/cli-engine/file-enumerator.js +++ b/tests/lib/cli-engine/file-enumerator.js @@ -184,7 +184,7 @@ describe("FileEnumerator", () => { }); // https://github.com/eslint/eslint/issues/14742 - describe.only("with 5 directories ('{lib}', '{lib}/client', '{lib}/client/src', '{lib}/server', '{lib}/server/src') that contains two files '{lib}/client/src/one.js' and '{lib}/server/src/two.js'", () => { + describe("with 5 directories ('{lib}', '{lib}/client', '{lib}/client/src', '{lib}/server', '{lib}/server/src') that contains two files '{lib}/client/src/one.js' and '{lib}/server/src/two.js'", () => { const root = path.join("/Users/snitin315/Desktop/eslint/file-enumerator"); const files = { "{lib}/client/src/one.js": "console.log('one.js');", From b469c28a322cf4daec396e603928c05a9f563305 Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Sat, 18 Feb 2023 16:17:15 +0530 Subject: [PATCH 05/10] chore: revert unwanted changes --- lib/cli-engine/file-enumerator.js | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/lib/cli-engine/file-enumerator.js b/lib/cli-engine/file-enumerator.js index 2316a498dc4..5f2f6ac5923 100644 --- a/lib/cli-engine/file-enumerator.js +++ b/lib/cli-engine/file-enumerator.js @@ -287,8 +287,6 @@ class FileEnumerator { const set = new Set(); for (const pattern of patterns) { - - // console.log("🚀 ~ file: file-enumerator.js:290 ~ FileEnumerator ~ *iterateFiles ~ pattern", pattern) let foundRegardlessOfIgnored = false; let found = false; @@ -352,8 +350,6 @@ class FileEnumerator { } if (globInputPaths && isGlobPattern(pattern)) { return this._iterateFilesWithGlob(pattern, isDot); - - // return this._iterateFilesWithGlob(absolutePath, isDot); } return []; @@ -402,10 +398,6 @@ class FileEnumerator { _iterateFilesWithGlob(pattern, dotfiles) { debug(`Glob: ${pattern}`); - /* - * const directoryPath = path.resolve(getGlobParent(pattern)); - * const globPart = pattern.slice(directoryPath.length + 1); - */ const { cwd } = internalSlotsMap.get(this); const directoryPath = path.resolve(cwd, getGlobParent(pattern)); const absolutePath = path.resolve(cwd, pattern); @@ -418,8 +410,6 @@ class FileEnumerator { const recursive = /\*\*|\/|\\/u.test(globPart); const selector = new Minimatch(absolutePath, minimatchOpts); - // const selector = new Minimatch(pattern, minimatchOpts); - debug(`recursive? ${recursive}`); return this._iterateFilesRecursive( @@ -468,11 +458,6 @@ class FileEnumerator { { ignoreNotFoundError: true } ); } - - // console.log(options); - debug( - `Selector: ${filePath}, ${options.selector.match(filePath)}` - ); const matched = options.selector // Started with a glob pattern; choose by the pattern. @@ -559,4 +544,4 @@ class FileEnumerator { // Public Interface //------------------------------------------------------------------------------ -module.exports = { FileEnumerator }; +module.exports = { FileEnumerator }; \ No newline at end of file From 5d2172eeacc26cbdc8b2ab5cdbf9c7e68fbf111a Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Sat, 18 Feb 2023 16:19:05 +0530 Subject: [PATCH 06/10] test: fix root path --- tests/lib/cli-engine/file-enumerator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lib/cli-engine/file-enumerator.js b/tests/lib/cli-engine/file-enumerator.js index 93655219ce8..3a96cf5eb84 100644 --- a/tests/lib/cli-engine/file-enumerator.js +++ b/tests/lib/cli-engine/file-enumerator.js @@ -185,7 +185,7 @@ describe("FileEnumerator", () => { // https://github.com/eslint/eslint/issues/14742 describe("with 5 directories ('{lib}', '{lib}/client', '{lib}/client/src', '{lib}/server', '{lib}/server/src') that contains two files '{lib}/client/src/one.js' and '{lib}/server/src/two.js'", () => { - const root = path.join("/Users/snitin315/Desktop/eslint/file-enumerator"); + const root = path.join(os.tmpdir(), "eslint/file-enumerator"); const files = { "{lib}/client/src/one.js": "console.log('one.js');", "{lib}/server/src/two.js": "console.log('two.js');", From b3c4f4308bf7e95715dd4314d94acff7763e49ec Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Sat, 18 Feb 2023 16:22:21 +0530 Subject: [PATCH 07/10] chore: fix lint --- lib/cli-engine/file-enumerator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cli-engine/file-enumerator.js b/lib/cli-engine/file-enumerator.js index 5f2f6ac5923..4797127cf37 100644 --- a/lib/cli-engine/file-enumerator.js +++ b/lib/cli-engine/file-enumerator.js @@ -544,4 +544,4 @@ class FileEnumerator { // Public Interface //------------------------------------------------------------------------------ -module.exports = { FileEnumerator }; \ No newline at end of file +module.exports = { FileEnumerator }; From ce5d4721fb2aa1adfffe73582e4ddb5ba7c3992e Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Sat, 25 Feb 2023 11:20:31 +0530 Subject: [PATCH 08/10] fix: correctly iterate files matched by glob patterns for new config system --- lib/eslint/eslint-helpers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/eslint/eslint-helpers.js b/lib/eslint/eslint-helpers.js index 5c5ed299c68..b28a87974dc 100644 --- a/lib/eslint/eslint-helpers.js +++ b/lib/eslint/eslint-helpers.js @@ -526,9 +526,9 @@ async function findFiles({ } // save patterns for later use based on whether globs are enabled - if (globInputPaths && isGlobPattern(filePath)) { + if (globInputPaths && isGlobPattern(pattern)) { - const basePath = globParent(filePath); + const basePath = path.resolve(cwd, globParent(pattern)); // group in cwd if possible and split out others if (isPathInside(basePath, cwd)) { From 4a7fc6fa73d05b609b2817990f3422ff9810e537 Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Sat, 25 Feb 2023 16:02:49 +0530 Subject: [PATCH 09/10] test: add case for flat config --- .../{curly-path}/client/eslint.config.js | 1 + tests/fixtures/{curly-path}/client/src/one.js | 1 + .../{curly-path}/server/eslint.config.js | 1 + tests/fixtures/{curly-path}/server/src/two.js | 1 + tests/lib/eslint/flat-eslint.js | 17 +++++++++++++++++ 5 files changed, 21 insertions(+) create mode 100644 tests/fixtures/{curly-path}/client/eslint.config.js create mode 100644 tests/fixtures/{curly-path}/client/src/one.js create mode 100644 tests/fixtures/{curly-path}/server/eslint.config.js create mode 100644 tests/fixtures/{curly-path}/server/src/two.js diff --git a/tests/fixtures/{curly-path}/client/eslint.config.js b/tests/fixtures/{curly-path}/client/eslint.config.js new file mode 100644 index 00000000000..cab59b0a888 --- /dev/null +++ b/tests/fixtures/{curly-path}/client/eslint.config.js @@ -0,0 +1 @@ +module.exports = { rules: { "no-console": "off" } }; diff --git a/tests/fixtures/{curly-path}/client/src/one.js b/tests/fixtures/{curly-path}/client/src/one.js new file mode 100644 index 00000000000..0dab8b6bcb0 --- /dev/null +++ b/tests/fixtures/{curly-path}/client/src/one.js @@ -0,0 +1 @@ +console.log("one"); diff --git a/tests/fixtures/{curly-path}/server/eslint.config.js b/tests/fixtures/{curly-path}/server/eslint.config.js new file mode 100644 index 00000000000..7e8b0562ad8 --- /dev/null +++ b/tests/fixtures/{curly-path}/server/eslint.config.js @@ -0,0 +1 @@ +module.exports = { rules: { "no-console": "warn" } }; diff --git a/tests/fixtures/{curly-path}/server/src/two.js b/tests/fixtures/{curly-path}/server/src/two.js new file mode 100644 index 00000000000..ef0e38f5b55 --- /dev/null +++ b/tests/fixtures/{curly-path}/server/src/two.js @@ -0,0 +1 @@ +console.log("two"); diff --git a/tests/lib/eslint/flat-eslint.js b/tests/lib/eslint/flat-eslint.js index ee17c3213cc..2321afaef1e 100644 --- a/tests/lib/eslint/flat-eslint.js +++ b/tests/lib/eslint/flat-eslint.js @@ -850,6 +850,23 @@ describe("FlatESLint", () => { assert.strictEqual(results[0].suppressedMessages.length, 0); }); + // https://github.com/eslint/eslint/issues/14742 + it.only("should run", async () => { + eslint = new FlatESLint({ + cwd: getFixturePath("{curly-path}", "server") + }); + const results = await eslint.lintFiles(["src/**/*.{js,json}"]); + + assert.strictEqual(results.length, 1); + assert.strictEqual(results[0].messages.length, 1); + assert.strictEqual(results[0].messages[0].ruleId, "no-console"); + assert.strictEqual( + results[0].filePath, + getFixturePath("{curly-path}/server/src/two.js") + ); + assert.strictEqual(results[0].suppressedMessages.length, 0); + }); + // https://github.com/eslint/eslint/issues/16265 describe("Dot files in searches", () => { From 56797345cd2974f2cf3c009990489cee3043e6cf Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Sat, 25 Feb 2023 16:23:42 +0530 Subject: [PATCH 10/10] chore: remove .only --- tests/lib/eslint/flat-eslint.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lib/eslint/flat-eslint.js b/tests/lib/eslint/flat-eslint.js index 2321afaef1e..e1e82401041 100644 --- a/tests/lib/eslint/flat-eslint.js +++ b/tests/lib/eslint/flat-eslint.js @@ -851,7 +851,7 @@ describe("FlatESLint", () => { }); // https://github.com/eslint/eslint/issues/14742 - it.only("should run", async () => { + it("should run", async () => { eslint = new FlatESLint({ cwd: getFixturePath("{curly-path}", "server") });