From 46017f1f44e62353db1da0a120c4e1388a230f3c Mon Sep 17 00:00:00 2001 From: "Nicholas C. Zakas" Date: Thu, 1 Sep 2022 13:47:34 -0700 Subject: [PATCH 1/5] fix: Ensure globbing doesn't include subdirectories Fixes #16260 --- lib/eslint/eslint-helpers.js | 24 +++++++++++++++---- tests/fixtures/shallow-glob/eslint.config.js | 5 ++++ tests/fixtures/shallow-glob/subdir/broken.js | 1 + .../shallow-glob/target-dir/passing.js | 1 + tests/lib/eslint/flat-eslint.js | 13 ++++++++++ 5 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 tests/fixtures/shallow-glob/eslint.config.js create mode 100644 tests/fixtures/shallow-glob/subdir/broken.js create mode 100644 tests/fixtures/shallow-glob/target-dir/passing.js diff --git a/lib/eslint/eslint-helpers.js b/lib/eslint/eslint-helpers.js index 442686e56bf..d23af3e6ea9 100644 --- a/lib/eslint/eslint-helpers.js +++ b/lib/eslint/eslint-helpers.js @@ -126,7 +126,7 @@ async function findFiles({ const filePaths = patterns.map(filePath => path.resolve(cwd, filePath)); const stats = await Promise.all( filePaths.map( - filePath => fsp.stat(filePath).catch(() => {}) + filePath => fsp.stat(filePath).catch(() => { }) ) ); @@ -162,16 +162,32 @@ async function findFiles({ return false; } + // patterns starting with ** always apply + if (filePattern.startsWith("**")) { + return true; + } + // not sure how to handle negated patterns yet if (filePattern.startsWith("!")) { return false; } - // check if the pattern would be inside the cwd or not + // check if the pattern would be inside the config base path or not const fullFilePattern = path.join(cwd, filePattern); - const relativeFilePattern = path.relative(configs.basePath, fullFilePattern); + const patternRelativeToConfigBasePath = path.relative(configs.basePath, fullFilePattern); + + if (patternRelativeToConfigBasePath.startsWith("..")) { + return false; + } + + // check if the pattern is inside the directory or not + const patternRelativeToFilePath = path.relative(filePath, fullFilePattern); + + if (patternRelativeToFilePath.startsWith("..")) { + return false; + } - return !relativeFilePattern.startsWith(".."); + return true; }) .map(filePattern => { if (filePattern.startsWith("**")) { diff --git a/tests/fixtures/shallow-glob/eslint.config.js b/tests/fixtures/shallow-glob/eslint.config.js new file mode 100644 index 00000000000..211719ddb90 --- /dev/null +++ b/tests/fixtures/shallow-glob/eslint.config.js @@ -0,0 +1,5 @@ +module.exports = [ + { + files: ["subdir/*.js"] + } +]; diff --git a/tests/fixtures/shallow-glob/subdir/broken.js b/tests/fixtures/shallow-glob/subdir/broken.js new file mode 100644 index 00000000000..d280fee2fdc --- /dev/null +++ b/tests/fixtures/shallow-glob/subdir/broken.js @@ -0,0 +1 @@ +module.exports = /* intentional syntax error */ diff --git a/tests/fixtures/shallow-glob/target-dir/passing.js b/tests/fixtures/shallow-glob/target-dir/passing.js new file mode 100644 index 00000000000..ec01c2c1416 --- /dev/null +++ b/tests/fixtures/shallow-glob/target-dir/passing.js @@ -0,0 +1 @@ +module.exports = true; diff --git a/tests/lib/eslint/flat-eslint.js b/tests/lib/eslint/flat-eslint.js index 1af6c2e1d8b..4c6f9df162a 100644 --- a/tests/lib/eslint/flat-eslint.js +++ b/tests/lib/eslint/flat-eslint.js @@ -784,6 +784,19 @@ describe("FlatESLint", () => { assert.strictEqual(results[0].suppressedMessages.length, 0); }); + // https://github.com/eslint/eslint/issues/16260 + it("should report zero messages when given a directory with a .js and config file specifying a subdirectory", async () => { + eslint = new FlatESLint({ + ignore: false, + cwd: getFixturePath("shallow-glob") + }); + const results = await eslint.lintFiles(["target-dir"]); + + assert.strictEqual(results.length, 1); + assert.strictEqual(results[0].messages.length, 0); + assert.strictEqual(results[0].suppressedMessages.length, 0); + }); + it("should report zero messages when given a '**' pattern with a .js and a .js2 file", async () => { eslint = new FlatESLint({ ignore: false, From 315dd711ac7242dd2aee5f4e4c61aa0bb133c603 Mon Sep 17 00:00:00 2001 From: Jugal Thakkar <2640821+jugalthakkar@users.noreply.github.com> Date: Mon, 5 Sep 2022 23:08:35 +0530 Subject: [PATCH 2/5] docs: copy & use main package version in docs on release (#16252) * docs: update docs package ver from main on release fixes https://github.com/eslint/eslint/issues/16212 * docs: read docs package ver instead of main fixes https://github.com/eslint/eslint/issues/16212 * docs: add newline to updated docs package json Co-authored-by: Milos Djermanovic * docs: update docs package json version Co-authored-by: Milos Djermanovic --- Makefile.js | 7 +++++++ docs/package.json | 2 +- docs/src/_data/eslintVersion.js | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Makefile.js b/Makefile.js index 1f353687398..a4b9f8bc4c1 100644 --- a/Makefile.js +++ b/Makefile.js @@ -287,6 +287,13 @@ function generateRelease() { generateBlogPost(releaseInfo); commitSiteToGit(`v${releaseInfo.version}`); + echo("Updating version in docs package"); + const docsPackagePath = path.join(__dirname, "docs", "package.json"); + const docsPackage = require(docsPackagePath); + + docsPackage.version = releaseInfo.version; + fs.writeFileSync(docsPackagePath, `${JSON.stringify(docsPackage, null, 4)}\n`); + echo("Updating commit with docs data"); exec("git add docs/ && git commit --amend --no-edit"); exec(`git tag -a -f v${releaseInfo.version} -m ${releaseInfo.version}`); diff --git a/docs/package.json b/docs/package.json index 558d41f97a9..6137ce86a2e 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,7 +1,7 @@ { "name": "docs-eslint", "private": true, - "version": "1.0.0", + "version": "8.23.0", "description": "", "main": "index.js", "keywords": [], diff --git a/docs/src/_data/eslintVersion.js b/docs/src/_data/eslintVersion.js index cd60276b37a..24964276c0d 100644 --- a/docs/src/_data/eslintVersion.js +++ b/docs/src/_data/eslintVersion.js @@ -14,7 +14,7 @@ const path = require("path"); // Initialization //----------------------------------------------------------------------------- -const pkgPath = path.resolve(__dirname, "../../../package.json"); +const pkgPath = path.resolve(__dirname, "../../package.json"); const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8")); const { ESLINT_VERSION } = process.env; @@ -23,7 +23,7 @@ const { ESLINT_VERSION } = process.env; //----------------------------------------------------------------------------- /* - * Because we want to differentiate between the development branch and the + * Because we want to differentiate between the development branch and the * most recent release, we need a way to override the version. The * ESLINT_VERSION environment variable allows us to set this to override * the value displayed on the website. The most common case is we will set From dd9612cedc9d12f756c00244c49610c89176e575 Mon Sep 17 00:00:00 2001 From: Milos Djermanovic Date: Mon, 5 Sep 2022 20:15:10 +0200 Subject: [PATCH 3/5] chore: enable linting `.eleventy.js` again (#16274) --- Makefile.js | 2 +- eslint.config.js | 19 +++---------------- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/Makefile.js b/Makefile.js index a4b9f8bc4c1..25e6345cbe6 100644 --- a/Makefile.js +++ b/Makefile.js @@ -545,7 +545,7 @@ target.lintDocsJS = function([fix = false] = []) { let errors = 0; echo("Validating JavaScript files in the docs directory"); - const lastReturn = exec(`${ESLINT}${fix ? "--fix" : ""} docs`); + const lastReturn = exec(`${ESLINT}${fix ? "--fix" : ""} docs/.eleventy.js`); if (lastReturn.code !== 0) { errors++; diff --git a/eslint.config.js b/eslint.config.js index 8df362209a1..2156ebe1eaa 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -77,10 +77,11 @@ function createInternalFilesPatterns(pattern = null) { } module.exports = [ - ...compat.extends("eslint", "plugin:eslint-plugin/recommended"), + ...compat.extends("eslint"), { plugins: { - "internal-rules": internalPlugin + "internal-rules": internalPlugin, + "eslint-plugin": eslintPlugin }, languageOptions: { ecmaVersion: "latest" @@ -96,20 +97,6 @@ module.exports = [ } }, rules: { - "eslint-plugin/consistent-output": "error", - "eslint-plugin/no-deprecated-context-methods": "error", - "eslint-plugin/no-only-tests": "error", - "eslint-plugin/prefer-message-ids": "error", - "eslint-plugin/prefer-output-null": "error", - "eslint-plugin/prefer-placeholders": "error", - "eslint-plugin/prefer-replace-text": "error", - "eslint-plugin/report-message-format": ["error", "[^a-z].*\\.$"], - "eslint-plugin/require-meta-docs-description": "error", - "eslint-plugin/require-meta-has-suggestions": "error", - "eslint-plugin/require-meta-schema": "error", - "eslint-plugin/require-meta-type": "error", - "eslint-plugin/test-case-property-ordering": "error", - "eslint-plugin/test-case-shorthand-strings": "error", "internal-rules/multiline-comment-style": "error" } }, From 1f9ccdc3dd27e0d20db0b1050e22f8a83b1e2788 Mon Sep 17 00:00:00 2001 From: "Nicholas C. Zakas" Date: Mon, 5 Sep 2022 13:32:27 -0700 Subject: [PATCH 4/5] Fix filtering of globs --- lib/eslint/eslint-helpers.js | 16 ++++--- .../shallow-glob/subdir/subsubdir/broken.js | 1 + .../shallow-glob/subdir/subsubdir/plain.jsx | 1 + tests/lib/eslint/flat-eslint.js | 42 +++++++++++++++---- 4 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 tests/fixtures/shallow-glob/subdir/subsubdir/broken.js create mode 100644 tests/fixtures/shallow-glob/subdir/subsubdir/plain.jsx diff --git a/lib/eslint/eslint-helpers.js b/lib/eslint/eslint-helpers.js index d23af3e6ea9..4ac41efbd61 100644 --- a/lib/eslint/eslint-helpers.js +++ b/lib/eslint/eslint-helpers.js @@ -15,6 +15,7 @@ const fsp = fs.promises; const isGlob = require("is-glob"); const globby = require("globby"); const hash = require("../cli-engine/hash"); +const minimatch = require("minimatch"); //----------------------------------------------------------------------------- // Errors @@ -157,16 +158,16 @@ async function findFiles({ return false; } - // patterns ending with * are not used for file search - if (filePattern.endsWith("*")) { - return false; - } - // patterns starting with ** always apply if (filePattern.startsWith("**")) { return true; } + // patterns ending with * are not used for file search + if (filePattern.endsWith("*")) { + return false; + } + // not sure how to handle negated patterns yet if (filePattern.startsWith("!")) { return false; @@ -180,6 +181,11 @@ async function findFiles({ return false; } + // check if the pattern matches + if (minimatch(filePath, path.dirname(fullFilePattern))) { + return true; + } + // check if the pattern is inside the directory or not const patternRelativeToFilePath = path.relative(filePath, fullFilePattern); diff --git a/tests/fixtures/shallow-glob/subdir/subsubdir/broken.js b/tests/fixtures/shallow-glob/subdir/subsubdir/broken.js new file mode 100644 index 00000000000..2e1fe2e76a2 --- /dev/null +++ b/tests/fixtures/shallow-glob/subdir/subsubdir/broken.js @@ -0,0 +1 @@ +function( {} // intentional syntax error diff --git a/tests/fixtures/shallow-glob/subdir/subsubdir/plain.jsx b/tests/fixtures/shallow-glob/subdir/subsubdir/plain.jsx new file mode 100644 index 00000000000..e901f01b487 --- /dev/null +++ b/tests/fixtures/shallow-glob/subdir/subsubdir/plain.jsx @@ -0,0 +1 @@ +foo; diff --git a/tests/lib/eslint/flat-eslint.js b/tests/lib/eslint/flat-eslint.js index 4c6f9df162a..8deecf1a2d7 100644 --- a/tests/lib/eslint/flat-eslint.js +++ b/tests/lib/eslint/flat-eslint.js @@ -785,16 +785,42 @@ describe("FlatESLint", () => { }); // https://github.com/eslint/eslint/issues/16260 - it("should report zero messages when given a directory with a .js and config file specifying a subdirectory", async () => { - eslint = new FlatESLint({ - ignore: false, - cwd: getFixturePath("shallow-glob") + describe("Globbing based on configs", () => { + it("should report zero messages when given a directory with a .js and config file specifying a subdirectory", async () => { + eslint = new FlatESLint({ + ignore: false, + cwd: getFixturePath("shallow-glob") + }); + const results = await eslint.lintFiles(["target-dir"]); + + assert.strictEqual(results.length, 1); + assert.strictEqual(results[0].messages.length, 0); + assert.strictEqual(results[0].suppressedMessages.length, 0); }); - const results = await eslint.lintFiles(["target-dir"]); - assert.strictEqual(results.length, 1); - assert.strictEqual(results[0].messages.length, 0); - assert.strictEqual(results[0].suppressedMessages.length, 0); + it("should glob for .jsx file in a subdirectory of the passed-in directory and not glob for any other patterns", async () => { + eslint = new FlatESLint({ + ignore: false, + overrideConfigFile: true, + overrideConfig: { + files: ["subdir/**/*.jsx", "target-dir/*.js"], + languageOptions: { + parserOptions: { + jsx: true + } + } + }, + cwd: getFixturePath("shallow-glob") + }); + const results = await eslint.lintFiles(["subdir/subsubdir"]); + + assert.strictEqual(results.length, 2); + assert.strictEqual(results[0].messages.length, 1); + assert(results[0].messages[0].fatal, "Fatal error expected."); + assert.strictEqual(results[0].suppressedMessages.length, 0); + assert.strictEqual(results[1].messages.length, 0); + assert.strictEqual(results[1].suppressedMessages.length, 0); + }); }); it("should report zero messages when given a '**' pattern with a .js and a .js2 file", async () => { From 8fc387c4d71b52963b70bcd8065938a23dce16f3 Mon Sep 17 00:00:00 2001 From: "Nicholas C. Zakas" Date: Wed, 7 Sep 2022 12:51:08 -0700 Subject: [PATCH 5/5] Enable partial matching of globs --- lib/eslint/eslint-helpers.js | 2 +- tests/lib/eslint/flat-eslint.js | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/lib/eslint/eslint-helpers.js b/lib/eslint/eslint-helpers.js index 4ac41efbd61..8001ddd32ee 100644 --- a/lib/eslint/eslint-helpers.js +++ b/lib/eslint/eslint-helpers.js @@ -182,7 +182,7 @@ async function findFiles({ } // check if the pattern matches - if (minimatch(filePath, path.dirname(fullFilePattern))) { + if (minimatch(filePath, path.dirname(fullFilePattern), { partial: true })) { return true; } diff --git a/tests/lib/eslint/flat-eslint.js b/tests/lib/eslint/flat-eslint.js index 8deecf1a2d7..47d8cbbfbd8 100644 --- a/tests/lib/eslint/flat-eslint.js +++ b/tests/lib/eslint/flat-eslint.js @@ -821,6 +821,33 @@ describe("FlatESLint", () => { assert.strictEqual(results[1].messages.length, 0); assert.strictEqual(results[1].suppressedMessages.length, 0); }); + + it("should glob for all files in subdir when passed-in on the command line with a partial matching glob", async () => { + eslint = new FlatESLint({ + ignore: false, + overrideConfigFile: true, + overrideConfig: { + files: ["s*/subsubdir/*.jsx", "target-dir/*.js"], + languageOptions: { + parserOptions: { + jsx: true + } + } + }, + cwd: getFixturePath("shallow-glob") + }); + const results = await eslint.lintFiles(["subdir"]); + + assert.strictEqual(results.length, 3); + assert.strictEqual(results[0].messages.length, 1); + assert(results[0].messages[0].fatal, "Fatal error expected."); + assert.strictEqual(results[0].suppressedMessages.length, 0); + assert.strictEqual(results[1].messages.length, 1); + assert(results[0].messages[0].fatal, "Fatal error expected."); + assert.strictEqual(results[1].suppressedMessages.length, 0); + assert.strictEqual(results[2].messages.length, 0); + assert.strictEqual(results[2].suppressedMessages.length, 0); + }); }); it("should report zero messages when given a '**' pattern with a .js and a .js2 file", async () => {