diff --git a/lib/eslint/eslint-helpers.js b/lib/eslint/eslint-helpers.js index 9bfd751cb2b..e25b10e8bc4 100644 --- a/lib/eslint/eslint-helpers.js +++ b/lib/eslint/eslint-helpers.js @@ -795,7 +795,7 @@ function processOptions({ // when overrideConfigFile is true that means don't do config file lookup configFile: overrideConfigFile === true ? false : overrideConfigFile, overrideConfig, - cwd, + cwd: path.normalize(cwd), errorOnUnmatchedPattern, fix, fixTypes, diff --git a/lib/eslint/eslint.js b/lib/eslint/eslint.js index e1d2116944e..15e6b3dee41 100644 --- a/lib/eslint/eslint.js +++ b/lib/eslint/eslint.js @@ -289,7 +289,7 @@ function processOptions({ cacheLocation, cacheStrategy, configFile: overrideConfigFile, - cwd, + cwd: path.normalize(cwd), errorOnUnmatchedPattern, extensions, fix, diff --git a/tests/fixtures/example-app3/.eslintignore b/tests/fixtures/example-app3/.eslintignore new file mode 100644 index 00000000000..e5999645160 --- /dev/null +++ b/tests/fixtures/example-app3/.eslintignore @@ -0,0 +1 @@ +src/dist diff --git a/tests/fixtures/example-app3/.eslintrc.js b/tests/fixtures/example-app3/.eslintrc.js new file mode 100644 index 00000000000..86a595d362c --- /dev/null +++ b/tests/fixtures/example-app3/.eslintrc.js @@ -0,0 +1,9 @@ +module.exports = { + parserOptions: { + ecmaVersion: 2020, + }, + 'root': true, + 'rules': { + 'semi': 'error', + }, + }; diff --git a/tests/fixtures/example-app3/eslint.config.js b/tests/fixtures/example-app3/eslint.config.js new file mode 100644 index 00000000000..7f94a016cdc --- /dev/null +++ b/tests/fixtures/example-app3/eslint.config.js @@ -0,0 +1,10 @@ +module.exports = [ + { + ignores: ["src/dist"] + }, + { + rules: { + semi: "error" + } + } +]; diff --git a/tests/fixtures/example-app3/node_modules/eslint-formatter-cwd/index.js b/tests/fixtures/example-app3/node_modules/eslint-formatter-cwd/index.js new file mode 100644 index 00000000000..ca853b3a44d --- /dev/null +++ b/tests/fixtures/example-app3/node_modules/eslint-formatter-cwd/index.js @@ -0,0 +1 @@ +module.exports = (_, { cwd }) => cwd; diff --git a/tests/fixtures/example-app3/node_modules/eslint-formatter-cwd/package.json b/tests/fixtures/example-app3/node_modules/eslint-formatter-cwd/package.json new file mode 100644 index 00000000000..0967ef424bc --- /dev/null +++ b/tests/fixtures/example-app3/node_modules/eslint-formatter-cwd/package.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/example-app3/node_modules/eslint-plugin-test/index.js b/tests/fixtures/example-app3/node_modules/eslint-plugin-test/index.js new file mode 100644 index 00000000000..50d288c6101 --- /dev/null +++ b/tests/fixtures/example-app3/node_modules/eslint-plugin-test/index.js @@ -0,0 +1,19 @@ +module.exports = { + rules: { + "report-cwd": { + meta: { + schema: [] + }, + create(context) { + return { + Program(node) { + context.report({ + node, + message: context.cwd + }); + } + } + } + } + } +} diff --git a/tests/fixtures/example-app3/node_modules/eslint-plugin-test/package.json b/tests/fixtures/example-app3/node_modules/eslint-plugin-test/package.json new file mode 100644 index 00000000000..0967ef424bc --- /dev/null +++ b/tests/fixtures/example-app3/node_modules/eslint-plugin-test/package.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/example-app3/src/1.js b/tests/fixtures/example-app3/src/1.js new file mode 100644 index 00000000000..e14c4f2a956 --- /dev/null +++ b/tests/fixtures/example-app3/src/1.js @@ -0,0 +1 @@ +console.log(1) diff --git a/tests/fixtures/example-app3/src/dist/2.js b/tests/fixtures/example-app3/src/dist/2.js new file mode 100644 index 00000000000..32926e25ddb --- /dev/null +++ b/tests/fixtures/example-app3/src/dist/2.js @@ -0,0 +1 @@ +console.log(2) diff --git a/tests/lib/eslint/eslint.js b/tests/lib/eslint/eslint.js index a422f4b867f..cb43823fbc5 100644 --- a/tests/lib/eslint/eslint.js +++ b/tests/lib/eslint/eslint.js @@ -126,6 +126,28 @@ describe("ESLint", () => { } }); + it("should normalize 'options.cwd'.", async () => { + const cwd = getFixturePath("example-app3"); + const engine = new ESLint({ + cwd: `${cwd}${path.sep}foo${path.sep}..`, // `/foo/..` should be normalized to `` + useEslintrc: false, + overrideConfig: { + plugins: ["test"], + rules: { + "test/report-cwd": "error" + } + } + }); + const results = await engine.lintText(""); + + assert.strictEqual(results[0].messages[0].ruleId, "test/report-cwd"); + assert.strictEqual(results[0].messages[0].message, cwd); + + const formatter = await engine.loadFormatter("cwd"); + + assert.strictEqual(formatter.format(results), cwd); + }); + it("should report one fatal message when given a path by --ignore-path that is not a file when ignore is true.", () => { assert.throws(() => { // eslint-disable-next-line no-new -- Check for throwing @@ -6945,4 +6967,50 @@ describe("ESLint", () => { }); }); }); + + // only works on a Windows machine + if (os.platform() === "win32") { + + // https://github.com/eslint/eslint/issues/17042 + describe("with cwd that is using forward slash on Windows", () => { + const cwd = getFixturePath("example-app3"); + const cwdForwardSlash = cwd.replace(/\\/gu, "/"); + + it("should correctly handle ignore patterns", async () => { + const engine = new ESLint({ cwd: cwdForwardSlash }); + const results = await engine.lintFiles(["./src"]); + + // src/dist/2.js should be ignored + assert.strictEqual(results.length, 1); + assert.strictEqual(results[0].filePath, path.join(cwd, "src\\1.js")); + }); + + it("should pass cwd with backslashes to rules", async () => { + const engine = new ESLint({ + cwd: cwdForwardSlash, + useEslintrc: false, + overrideConfig: { + plugins: ["test"], + rules: { + "test/report-cwd": "error" + } + } + }); + const results = await engine.lintText(""); + + assert.strictEqual(results[0].messages[0].ruleId, "test/report-cwd"); + assert.strictEqual(results[0].messages[0].message, cwd); + }); + + it("should pass cwd with backslashes to formatters", async () => { + const engine = new ESLint({ + cwd: cwdForwardSlash + }); + const results = await engine.lintText(""); + const formatter = await engine.loadFormatter("cwd"); + + assert.strictEqual(formatter.format(results), cwd); + }); + }); + } }); diff --git a/tests/lib/eslint/flat-eslint.js b/tests/lib/eslint/flat-eslint.js index ffad0a793ea..0a692e9e7f9 100644 --- a/tests/lib/eslint/flat-eslint.js +++ b/tests/lib/eslint/flat-eslint.js @@ -140,6 +140,30 @@ describe("FlatESLint", () => { } }); + it("should normalize 'options.cwd'.", async () => { + const cwd = getFixturePath("example-app3"); + const engine = new FlatESLint({ + cwd: `${cwd}${path.sep}foo${path.sep}..`, // `/foo/..` should be normalized to `` + overrideConfigFile: true, + overrideConfig: { + plugins: { + test: require(path.join(cwd, "node_modules", "eslint-plugin-test")) + }, + rules: { + "test/report-cwd": "error" + } + } + }); + const results = await engine.lintText(""); + + assert.strictEqual(results[0].messages[0].ruleId, "test/report-cwd"); + assert.strictEqual(results[0].messages[0].message, cwd); + + const formatter = await engine.loadFormatter("cwd"); + + assert.strictEqual(formatter.format(results), cwd); + }); + // https://github.com/eslint/eslint/issues/2380 it("should not modify baseConfig when format is specified", () => { const customBaseConfig = { root: true }; @@ -5701,6 +5725,54 @@ describe("FlatESLint", () => { }); }); + // only works on a Windows machine + if (os.platform() === "win32") { + + // https://github.com/eslint/eslint/issues/17042 + describe("with cwd that is using forward slash on Windows", () => { + const cwd = getFixturePath("example-app3"); + const cwdForwardSlash = cwd.replace(/\\/gu, "/"); + + it("should correctly handle ignore patterns", async () => { + const engine = new FlatESLint({ cwd: cwdForwardSlash }); + const results = await engine.lintFiles(["./src"]); + + // src/dist/2.js should be ignored + assert.strictEqual(results.length, 1); + assert.strictEqual(results[0].filePath, path.join(cwd, "src\\1.js")); + }); + + it("should pass cwd with backslashes to rules", async () => { + const engine = new FlatESLint({ + cwd: cwdForwardSlash, + overrideConfigFile: true, + overrideConfig: { + plugins: { + test: require(path.join(cwd, "node_modules", "eslint-plugin-test")) + }, + rules: { + "test/report-cwd": "error" + } + } + }); + const results = await engine.lintText(""); + + assert.strictEqual(results[0].messages[0].ruleId, "test/report-cwd"); + assert.strictEqual(results[0].messages[0].message, cwd); + }); + + it("should pass cwd with backslashes to formatters", async () => { + const engine = new FlatESLint({ + cwd: cwdForwardSlash + }); + const results = await engine.lintText(""); + const formatter = await engine.loadFormatter("cwd"); + + assert.strictEqual(formatter.format(results), cwd); + }); + }); + } + }); describe("shouldUseFlatConfig", () => {