From c50ae4f840d1ee9dc7b80a46c887398c0ec0a67c Mon Sep 17 00:00:00 2001 From: "Nicholas C. Zakas" Date: Tue, 15 Nov 2022 04:53:07 -0800 Subject: [PATCH] fix: Ensure that dot files are found with globs. (#16550) Previously, glob patterns didn't match dot files and couldn't be changed while we were using globby for flat config. Because we moved to our own glob search, we can now include dot files in our searches automatically. Fixes #16265 --- lib/eslint/eslint-helpers.js | 5 +- tests/fixtures/cli-engine/empty/.keep | 0 tests/fixtures/dot-files/.a.js | 1 + tests/fixtures/dot-files/.c.js | 1 + tests/fixtures/dot-files/b.js | 1 + tests/fixtures/dot-files/eslint.config.js | 8 +++ tests/lib/eslint/flat-eslint.js | 88 +++++++++++++++++++++-- 7 files changed, 97 insertions(+), 7 deletions(-) delete mode 100644 tests/fixtures/cli-engine/empty/.keep create mode 100644 tests/fixtures/dot-files/.a.js create mode 100644 tests/fixtures/dot-files/.c.js create mode 100644 tests/fixtures/dot-files/b.js create mode 100644 tests/fixtures/dot-files/eslint.config.js diff --git a/lib/eslint/eslint-helpers.js b/lib/eslint/eslint-helpers.js index bf91700ba35..5c5ed299c68 100644 --- a/lib/eslint/eslint-helpers.js +++ b/lib/eslint/eslint-helpers.js @@ -26,6 +26,7 @@ const isPathInside = require("is-path-inside"); const doFsWalk = util.promisify(fswalk.walk); const Minimatch = minimatch.Minimatch; +const MINIMATCH_OPTIONS = { dot: true }; //----------------------------------------------------------------------------- // Types @@ -158,7 +159,7 @@ function globMatch({ basePath, pattern }) { ? normalizeToPosix(path.relative(basePath, pattern)) : pattern; - const matcher = new Minimatch(patternToUse); + const matcher = new Minimatch(patternToUse, MINIMATCH_OPTIONS); const fsWalkSettings = { @@ -257,7 +258,7 @@ async function globSearch({ relativeToPatterns.set(patternToUse, patterns[i]); - return new minimatch.Minimatch(patternToUse); + return new Minimatch(patternToUse, MINIMATCH_OPTIONS); }); /* diff --git a/tests/fixtures/cli-engine/empty/.keep b/tests/fixtures/cli-engine/empty/.keep deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/tests/fixtures/dot-files/.a.js b/tests/fixtures/dot-files/.a.js new file mode 100644 index 00000000000..e5f581a97a9 --- /dev/null +++ b/tests/fixtures/dot-files/.a.js @@ -0,0 +1 @@ +console.log("Running"); diff --git a/tests/fixtures/dot-files/.c.js b/tests/fixtures/dot-files/.c.js new file mode 100644 index 00000000000..e5f581a97a9 --- /dev/null +++ b/tests/fixtures/dot-files/.c.js @@ -0,0 +1 @@ +console.log("Running"); diff --git a/tests/fixtures/dot-files/b.js b/tests/fixtures/dot-files/b.js new file mode 100644 index 00000000000..e5f581a97a9 --- /dev/null +++ b/tests/fixtures/dot-files/b.js @@ -0,0 +1 @@ +console.log("Running"); diff --git a/tests/fixtures/dot-files/eslint.config.js b/tests/fixtures/dot-files/eslint.config.js new file mode 100644 index 00000000000..e0b84a703fd --- /dev/null +++ b/tests/fixtures/dot-files/eslint.config.js @@ -0,0 +1,8 @@ +module.exports = [ + { + files: ["*.js"] + }, + { + ignores: ["eslint.config.js"] + } +]; diff --git a/tests/lib/eslint/flat-eslint.js b/tests/lib/eslint/flat-eslint.js index 8f5b1024fbb..76dcb881847 100644 --- a/tests/lib/eslint/flat-eslint.js +++ b/tests/lib/eslint/flat-eslint.js @@ -24,6 +24,23 @@ const hash = require("../../../lib/cli-engine/hash"); const { unIndent, createCustomTeardown } = require("../../_utils"); const coreRules = require("../../../lib/rules"); +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Creates a directory if it doesn't already exist. + * @param {string} dirPath The path to the directory that should exist. + * @returns {void} + */ +function ensureDirectoryExists(dirPath) { + try { + fs.statSync(dirPath); + } catch { + fs.mkdirSync(dirPath); + } +} + //------------------------------------------------------------------------------ // Tests //------------------------------------------------------------------------------ @@ -773,7 +790,7 @@ describe("FlatESLint", () => { }); const results = await eslint.lintFiles(["fixtures/files/"]); - assert.strictEqual(results.length, 2); + assert.strictEqual(results.length, 3); assert.strictEqual(results[0].messages.length, 0); assert.strictEqual(results[1].messages.length, 0); assert.strictEqual(results[0].suppressedMessages.length, 0); @@ -823,6 +840,58 @@ describe("FlatESLint", () => { assert.strictEqual(results[0].suppressedMessages.length, 0); }); + // https://github.com/eslint/eslint/issues/16265 + describe("Dot files in searches", () => { + + it("should find dot files in current directory when a . pattern is used", async () => { + eslint = new FlatESLint({ + cwd: getFixturePath("dot-files") + }); + const results = await eslint.lintFiles(["."]); + + assert.strictEqual(results.length, 3); + assert.strictEqual(results[0].messages.length, 0); + assert.strictEqual(results[0].filePath, getFixturePath("dot-files/.a.js")); + assert.strictEqual(results[0].suppressedMessages.length, 0); + assert.strictEqual(results[1].messages.length, 0); + assert.strictEqual(results[1].filePath, getFixturePath("dot-files/.c.js")); + assert.strictEqual(results[1].suppressedMessages.length, 0); + assert.strictEqual(results[2].messages.length, 0); + assert.strictEqual(results[2].filePath, getFixturePath("dot-files/b.js")); + assert.strictEqual(results[2].suppressedMessages.length, 0); + }); + + it("should find dot files in current directory when a *.js pattern is used", async () => { + eslint = new FlatESLint({ + cwd: getFixturePath("dot-files") + }); + const results = await eslint.lintFiles(["*.js"]); + + assert.strictEqual(results.length, 3); + assert.strictEqual(results[0].messages.length, 0); + assert.strictEqual(results[0].filePath, getFixturePath("dot-files/.a.js")); + assert.strictEqual(results[0].suppressedMessages.length, 0); + assert.strictEqual(results[1].messages.length, 0); + assert.strictEqual(results[1].filePath, getFixturePath("dot-files/.c.js")); + assert.strictEqual(results[1].suppressedMessages.length, 0); + assert.strictEqual(results[2].messages.length, 0); + assert.strictEqual(results[2].filePath, getFixturePath("dot-files/b.js")); + assert.strictEqual(results[2].suppressedMessages.length, 0); + }); + + it("should find dot files in current directory when a .a.js pattern is used", async () => { + eslint = new FlatESLint({ + cwd: getFixturePath("dot-files") + }); + const results = await eslint.lintFiles([".a.js"]); + + assert.strictEqual(results.length, 1); + assert.strictEqual(results[0].messages.length, 0); + assert.strictEqual(results[0].filePath, getFixturePath("dot-files/.a.js")); + assert.strictEqual(results[0].suppressedMessages.length, 0); + }); + }); + // https://github.com/eslint/eslint/issues/16275 describe("Glob patterns without matches", () => { @@ -992,11 +1061,13 @@ describe("FlatESLint", () => { }); const results = await eslint.lintFiles(["fixtures/files/*"]); - assert.strictEqual(results.length, 2); + assert.strictEqual(results.length, 3); assert.strictEqual(results[0].messages.length, 0); assert.strictEqual(results[1].messages.length, 0); + assert.strictEqual(results[2].messages.length, 0); assert.strictEqual(results[0].suppressedMessages.length, 0); assert.strictEqual(results[1].suppressedMessages.length, 0); + assert.strictEqual(results[2].suppressedMessages.length, 0); }); it("should resolve globs when 'globInputPaths' option is true", async () => { @@ -1009,11 +1080,13 @@ describe("FlatESLint", () => { }); const results = await eslint.lintFiles(["fixtures/files/*"]); - assert.strictEqual(results.length, 2); + assert.strictEqual(results.length, 3); assert.strictEqual(results[0].messages.length, 0); assert.strictEqual(results[1].messages.length, 0); + assert.strictEqual(results[2].messages.length, 0); assert.strictEqual(results[0].suppressedMessages.length, 0); assert.strictEqual(results[1].suppressedMessages.length, 0); + assert.strictEqual(results[2].suppressedMessages.length, 0); }); // only works on a Windows machine @@ -1029,11 +1102,13 @@ describe("FlatESLint", () => { }); const results = await eslint.lintFiles(["fixtures\\files\\*"]); - assert.strictEqual(results.length, 2); + assert.strictEqual(results.length, 3); assert.strictEqual(results[0].messages.length, 0); assert.strictEqual(results[1].messages.length, 0); + assert.strictEqual(results[2].messages.length, 0); assert.strictEqual(results[0].suppressedMessages.length, 0); assert.strictEqual(results[1].suppressedMessages.length, 0); + assert.strictEqual(results[2].suppressedMessages.length, 0); }); } @@ -1358,11 +1433,13 @@ describe("FlatESLint", () => { }); const results = await eslint.lintFiles(["fixtures/files/*.?s*"]); - assert.strictEqual(results.length, 2); + assert.strictEqual(results.length, 3); assert.strictEqual(results[0].messages.length, 0); assert.strictEqual(results[0].suppressedMessages.length, 0); assert.strictEqual(results[1].messages.length, 0); assert.strictEqual(results[1].suppressedMessages.length, 0); + assert.strictEqual(results[2].messages.length, 0); + assert.strictEqual(results[2].suppressedMessages.length, 0); }); it("should return one error message when given a config with rules with options and severity level set to error", async () => { @@ -2785,6 +2862,7 @@ describe("FlatESLint", () => { }); it("should throw if the directory exists and is empty", async () => { + ensureDirectoryExists(getFixturePath("cli-engine/empty")); await assert.rejects(async () => { await eslint.lintFiles(["empty"]); }, /No files matching 'empty' were found\./u);