diff --git a/Makefile.js b/Makefile.js index cbfc0c0ea02..64b52457943 100644 --- a/Makefile.js +++ b/Makefile.js @@ -518,11 +518,11 @@ target.lint = function([fix = false] = []) { * when analyzing `require()` calls from CJS modules in the `docs` directory. Since our release process does not run `npm install` * in the `docs` directory, linting would fail and break the release. Also, working on the main `eslint` package does not require * installing dependencies declared in `docs/package.json`, so most contributors will not have `docs/node_modules` locally. - * Therefore, we add `--ignore-pattern docs` to exclude linting the `docs` directory from this command. + * Therefore, we add `--ignore-pattern "docs/**"` to exclude linting the `docs` directory from this command. * There is a separate command `target.lintDocsJS` for linting JavaScript files in the `docs` directory. */ echo("Validating JavaScript files"); - lastReturn = exec(`${ESLINT}${fix ? "--fix" : ""} . --ignore-pattern docs`); + lastReturn = exec(`${ESLINT}${fix ? "--fix" : ""} . --ignore-pattern "docs/**"`); if (lastReturn.code !== 0) { errors++; } diff --git a/docs/src/user-guide/configuring/configuration-files-new.md b/docs/src/user-guide/configuring/configuration-files-new.md index cc7b42d7acc..38ee3eb9928 100644 --- a/docs/src/user-guide/configuring/configuration-files-new.md +++ b/docs/src/user-guide/configuring/configuration-files-new.md @@ -132,7 +132,7 @@ This configuration object applies to all files except those ending with `.config #### Globally ignoring files with `ignores` -If `ignores` is used without any other keys in the configuration object, then the patterns act as additional global ignores, similar to those found in `.eslintignore`. Here's an example: +If `ignores` is used without any other keys in the configuration object, then the patterns act as global ignores. Here's an example: ```js export default [ @@ -142,7 +142,7 @@ export default [ ]; ``` -This configuration specifies that all of the files in the `.config` directory should be ignored. This pattern is added after the patterns found in `.eslintignore`. +This configuration specifies that all of the files in the `.config` directory should be ignored. This pattern is added after the default patterns, which are `["**/node_modules/**", ".git/**"]`. #### Cascading configuration objects diff --git a/eslint.config.js b/eslint.config.js index 2156ebe1eaa..461171c5d01 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -78,6 +78,23 @@ function createInternalFilesPatterns(pattern = null) { module.exports = [ ...compat.extends("eslint"), + { + ignores: [ + "build/**", + "coverage/**", + "docs/**", + "!docs/.eleventy.js", + "jsdoc/**", + "templates/**", + "tests/bench/**", + "tests/fixtures/**", + "tests/performance/**", + "tmp/**", + "tools/internal-rules/node_modules/**", + "**/test.js", + "!**/.eslintrc.js" + ] + }, { plugins: { "internal-rules": internalPlugin, diff --git a/lib/cli.js b/lib/cli.js index 2fca65c1908..29718fbdf53 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -25,7 +25,6 @@ const fs = require("fs"), RuntimeInfo = require("./shared/runtime-info"); const { Legacy: { naming } } = require("@eslint/eslintrc"); const { findFlatConfigFile } = require("./eslint/flat-eslint"); -const { gitignoreToMinimatch } = require("@humanwhocodes/gitignore-to-minimatch"); const { ModuleImporter } = require("@humanwhocodes/module-importer"); const debug = require("debug")("eslint:cli"); @@ -145,7 +144,7 @@ async function translateOptions({ if (ignorePattern) { overrideConfig.push({ - ignores: ignorePattern.map(gitignoreToMinimatch) + ignores: ignorePattern }); } @@ -182,7 +181,6 @@ async function translateOptions({ fix: (fix || fixDryRun) && (quiet ? quietFixPredicate : true), fixTypes: fixType, ignore, - ignorePath, overrideConfig, overrideConfigFile, reportUnusedDisableDirectives: reportUnusedDisableDirectives ? "error" : void 0 @@ -193,6 +191,7 @@ async function translateOptions({ options.rulePaths = rulesdir; options.useEslintrc = eslintrc; options.extensions = ext; + options.ignorePath = ignorePath; } return options; diff --git a/lib/eslint/eslint-helpers.js b/lib/eslint/eslint-helpers.js index b776ca173ba..e257310f6e9 100644 --- a/lib/eslint/eslint-helpers.js +++ b/lib/eslint/eslint-helpers.js @@ -410,7 +410,6 @@ function processOptions({ fixTypes = null, // ← should be null by default because if it's an array then it suppresses rules that don't have the `meta.type` property. globInputPaths = true, ignore = true, - ignorePath = null, // ← should be null by default because if it's a string then it may throw ENOENT. ignorePatterns = null, overrideConfig = null, overrideConfigFile = null, @@ -441,6 +440,9 @@ function processOptions({ if (unknownOptionKeys.includes("globals")) { errors.push("'globals' has been removed. Please use the 'overrideConfig.languageOptions.globals' option instead."); } + if (unknownOptionKeys.includes("ignorePath")) { + errors.push("'ignorePath' has been removed."); + } if (unknownOptionKeys.includes("ignorePattern")) { errors.push("'ignorePattern' has been removed. Please use the 'overrideConfig.ignorePatterns' option instead."); } @@ -493,9 +495,6 @@ function processOptions({ if (typeof ignore !== "boolean") { errors.push("'ignore' must be a boolean."); } - if (!isNonEmptyString(ignorePath) && ignorePath !== null) { - errors.push("'ignorePath' must be a non-empty string or null."); - } if (typeof overrideConfig !== "object") { errors.push("'overrideConfig' must be an object or null."); } @@ -538,7 +537,6 @@ function processOptions({ fixTypes, globInputPaths, ignore, - ignorePath, ignorePatterns, reportUnusedDisableDirectives }; diff --git a/lib/eslint/flat-eslint.js b/lib/eslint/flat-eslint.js index f33241212f6..9f4eed011fa 100644 --- a/lib/eslint/flat-eslint.js +++ b/lib/eslint/flat-eslint.js @@ -16,7 +16,6 @@ const findUp = require("find-up"); const { version } = require("../../package.json"); const { Linter } = require("../linter"); const { getRuleFromConfig } = require("../config/flat-config-helpers"); -const { gitignoreToMinimatch } = require("@humanwhocodes/gitignore-to-minimatch"); const { Legacy: { ConfigOps: { @@ -28,7 +27,6 @@ const { } = require("@eslint/eslintrc"); const { - fileExists, findFiles, getCacheFile, @@ -76,9 +74,8 @@ const LintResultCache = require("../cli-engine/lint-result-cache"); * @property {boolean|Function} [fix] Execute in autofix mode. If a function, should return a boolean. * @property {string[]} [fixTypes] Array of rule types to apply fixes for. * @property {boolean} [globInputPaths] Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file. - * @property {boolean} [ignore] False disables use of .eslintignore. - * @property {string} [ignorePath] The ignore file to use instead of .eslintignore. - * @property {string[]} [ignorePatterns] Ignore file patterns to use in addition to .eslintignore. + * @property {boolean} [ignore] False disables all ignore patterns except for the default ones. + * @property {string[]} [ignorePatterns] Ignore file patterns to use in addition to config ignores. * @property {ConfigData} [overrideConfig] Override config object, overrides all configs used with this instance * @property {boolean|string} [overrideConfigFile] Searches for default config file when falsy; * doesn't do any config file lookup when `true`; considered to be a config filename @@ -151,30 +148,6 @@ function calculateStatsPerRun(results) { }); } -/** - * Loads global ignore patterns from an ignore file (usually .eslintignore). - * @param {string} filePath The filename to load. - * @returns {ignore} A function encapsulating the ignore patterns. - * @throws {Error} If the file cannot be read. - * @private - */ -async function loadIgnoreFilePatterns(filePath) { - debug(`Loading ignore file: ${filePath}`); - - try { - const ignoreFileText = await fs.readFile(filePath, { encoding: "utf8" }); - - return ignoreFileText - .split(/\r?\n/gu) - .filter(line => line.trim() !== "" && !line.startsWith("#")); - - } catch (e) { - debug(`Error reading ignore file: ${filePath}`); - e.message = `Cannot read ignore file: ${filePath}\nError: ${e.message}`; - throw e; - } -} - /** * Create rulesMeta object. * @param {Map} rules a map of rules from which to generate the object. @@ -319,7 +292,6 @@ async function calculateConfigArray(eslint, { overrideConfig, configFile, ignore: shouldIgnore, - ignorePath, ignorePatterns }) { @@ -364,22 +336,6 @@ async function calculateConfigArray(eslint, { configs.push(...slots.defaultConfigs); let allIgnorePatterns = []; - let ignoreFilePath; - - // load ignore file if necessary - if (shouldIgnore) { - if (ignorePath) { - ignoreFilePath = path.resolve(cwd, ignorePath); - allIgnorePatterns = await loadIgnoreFilePatterns(ignoreFilePath); - } else { - ignoreFilePath = path.resolve(cwd, ".eslintignore"); - - // no error if .eslintignore doesn't exist` - if (fileExists(ignoreFilePath)) { - allIgnorePatterns = await loadIgnoreFilePatterns(ignoreFilePath); - } - } - } // append command line ignore patterns if (ignorePatterns) { @@ -428,7 +384,7 @@ async function calculateConfigArray(eslint, { * so they can override default ignores. */ configs.push({ - ignores: allIgnorePatterns.map(gitignoreToMinimatch) + ignores: allIgnorePatterns }); } diff --git a/lib/options.js b/lib/options.js index ec370097be5..c43aad93276 100644 --- a/lib/options.js +++ b/lib/options.js @@ -129,6 +129,16 @@ module.exports = function(usingFlatConfig) { }; } + let ignorePathFlag; + + if (!usingFlatConfig) { + ignorePathFlag = { + option: "ignore-path", + type: "path::String", + description: "Specify path of ignore file" + }; + } + return optionator({ prepend: "eslint [options] file.js [file.js] [dir]", defaults: { @@ -203,11 +213,7 @@ module.exports = function(usingFlatConfig) { { heading: "Ignoring files" }, - { - option: "ignore-path", - type: "path::String", - description: "Specify path of ignore file" - }, + ignorePathFlag, { option: "ignore", type: "Boolean", diff --git a/package.json b/package.json index 20c2a19fe0b..a0a6ec63897 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,6 @@ "dependencies": { "@eslint/eslintrc": "^1.3.2", "@humanwhocodes/config-array": "^0.10.5", - "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", diff --git a/tests/fixtures/.eslintignore_empty b/tests/fixtures/.eslintignore_empty new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/fixtures/cli-engine/eslint.config_with_ignores2.js b/tests/fixtures/cli-engine/eslint.config_with_ignores2.js new file mode 100644 index 00000000000..0450eb699f2 --- /dev/null +++ b/tests/fixtures/cli-engine/eslint.config_with_ignores2.js @@ -0,0 +1,3 @@ +module.exports = [{ + ignores: ["**/fixtures/**"] +}]; diff --git a/tests/fixtures/eslint.config_with_ignores.js b/tests/fixtures/eslint.config_with_ignores.js new file mode 100644 index 00000000000..4640a3bf3e9 --- /dev/null +++ b/tests/fixtures/eslint.config_with_ignores.js @@ -0,0 +1,8 @@ +const eslintConfig = require("./eslint.config.js"); + +module.exports = [ + eslintConfig, + { + ignores: ["**/*.json", "**/*.js"] + } +]; diff --git a/tests/fixtures/eslint.config_with_ignores2.js b/tests/fixtures/eslint.config_with_ignores2.js new file mode 100644 index 00000000000..ec15bf421bc --- /dev/null +++ b/tests/fixtures/eslint.config_with_ignores2.js @@ -0,0 +1,8 @@ +const eslintConfig = require("./eslint.config.js"); + +module.exports = [ + eslintConfig, + { + ignores: ["**/undef.js", "undef2.js", "**/undef3.js"] + } +]; diff --git a/tests/lib/cli.js b/tests/lib/cli.js index a58a8c910fc..80ac5930701 100644 --- a/tests/lib/cli.js +++ b/tests/lib/cli.js @@ -658,23 +658,27 @@ describe("cli", () => { describe("when given a directory with eslint excluded files in the directory", () => { it(`should throw an error and not process any files with configType:${configType}`, async () => { - const ignorePath = getFixturePath(".eslintignore"); + const options = useFlatConfig + ? `--config ${getFixturePath("eslint.config_with_ignores.js")}` + : `--ignore-path ${getFixturePath(".eslintignore")}`; const filePath = getFixturePath("cli"); const expectedMessage = useFlatConfig ? `All files matched by '${filePath.replace(/\\/gu, "/")}/**/*.js' are ignored.` : `All files matched by '${filePath}' are ignored.`; await stdAssert.rejects(async () => { - await cli.execute(`--ignore-path ${ignorePath} ${filePath}`, null, useFlatConfig); + await cli.execute(`${options} ${filePath}`, null, useFlatConfig); }, new Error(expectedMessage)); }); }); describe("when given a file in excluded files list", () => { it(`should not process the file with configType:${configType}`, async () => { - const ignorePath = getFixturePath(".eslintignore"); + const options = useFlatConfig + ? `--config ${getFixturePath("eslint.config_with_ignores.js")}` + : `--ignore-path ${getFixturePath(".eslintignore")}`; const filePath = getFixturePath("passing.js"); - const exit = await cli.execute(`--ignore-path ${ignorePath} ${filePath}`, null, useFlatConfig); + const exit = await cli.execute(`${options} ${filePath}`, null, useFlatConfig); // a warning about the ignored file assert.isTrue(log.info.called); @@ -682,9 +686,11 @@ describe("cli", () => { }); it(`should process the file when forced with configType:${configType}`, async () => { - const ignorePath = getFixturePath(".eslintignore"); + const options = useFlatConfig + ? `--config ${getFixturePath("eslint.config_with_ignores.js")}` + : `--ignore-path ${getFixturePath(".eslintignore")}`; const filePath = getFixturePath("passing.js"); - const exit = await cli.execute(`--ignore-path ${ignorePath} --no-ignore ${filePath}`, null, useFlatConfig); + const exit = await cli.execute(`${options} --no-ignore ${filePath}`, null, useFlatConfig); // no warnings assert.isFalse(log.info.called); @@ -695,13 +701,39 @@ describe("cli", () => { describe("when given a pattern to ignore", () => { it(`should not process any files with configType:${configType}`, async () => { const ignoredFile = getFixturePath("cli/syntax-error.js"); + const ignorePathOption = useFlatConfig + ? "" + : "--ignore-path .eslintignore_empty"; const filePath = getFixturePath("cli/passing.js"); - const exit = await cli.execute(`--ignore-pattern cli/ ${ignoredFile} ${filePath}`, null, useFlatConfig); + const ignorePattern = useFlatConfig ? "cli/**" : "cli/"; + const exit = await cli.execute( + `--ignore-pattern ${ignorePattern} ${ignorePathOption} ${ignoredFile} ${filePath}`, null, useFlatConfig + ); // warnings about the ignored files assert.isTrue(log.info.called); assert.strictEqual(exit, 0); }); + + if (useFlatConfig) { + it("should not ignore files if the pattern is a path to a directory (with trailing slash)", async () => { + const filePath = getFixturePath("cli/syntax-error.js"); + const exit = await cli.execute(`--ignore-pattern cli/ ${filePath}`, null, true); + + // parsing error causes exit code 1 + assert.isTrue(log.info.called); + assert.strictEqual(exit, 1); + }); + + it("should not ignore files if the pattern is a path to a directory (without trailing slash)", async () => { + const filePath = getFixturePath("cli/syntax-error.js"); + const exit = await cli.execute(`--ignore-pattern cli ${filePath}`, null, true); + + // parsing error causes exit code 1 + assert.isTrue(log.info.called); + assert.strictEqual(exit, 1); + }); + } }); }); diff --git a/tests/lib/eslint/flat-eslint.js b/tests/lib/eslint/flat-eslint.js index 6da4176beca..f3f8b06dc01 100644 --- a/tests/lib/eslint/flat-eslint.js +++ b/tests/lib/eslint/flat-eslint.js @@ -128,6 +128,7 @@ describe("FlatESLint", () => { configFile: "", envs: [], globals: [], + ignorePath: ".gitignore", ignorePattern: [], parser: "", parserOptions: {}, @@ -136,7 +137,7 @@ describe("FlatESLint", () => { }), new RegExp(escapeStringRegExp([ "Invalid Options:", - "- Unknown options: cacheFile, configFile, envs, globals, ignorePattern, parser, parserOptions, rules" + "- Unknown options: cacheFile, configFile, envs, globals, ignorePath, ignorePattern, parser, parserOptions, rules" ].join("\n")), "u") ); }); @@ -154,7 +155,6 @@ describe("FlatESLint", () => { fixTypes: ["xyz"], globInputPaths: "", ignore: "", - ignorePath: "", overrideConfig: "", overrideConfigFile: "", plugins: "", @@ -172,7 +172,6 @@ describe("FlatESLint", () => { "- 'fixTypes' must be an array of any of \"directive\", \"problem\", \"suggestion\", and \"layout\".", "- 'globInputPaths' must be a boolean.", "- 'ignore' must be a boolean.", - "- 'ignorePath' must be a non-empty string or null.", "- 'overrideConfig' must be an object or null.", "- 'overrideConfigFile' must be a non-empty string, null, or true.", "- 'plugins' must be an object or null.", @@ -278,9 +277,8 @@ describe("FlatESLint", () => { it("should return a warning when given a filename by --stdin-filename in excluded files list if warnIgnored is true", async () => { eslint = new FlatESLint({ - ignorePath: getFixturePath(".eslintignore"), cwd: getFixturePath(".."), - overrideConfigFile: "fixtures/eslint.config.js" + overrideConfigFile: "fixtures/eslint.config_with_ignores.js" }); const options = { filePath: "fixtures/passing.js", warnIgnored: true }; @@ -302,9 +300,8 @@ describe("FlatESLint", () => { it("should not return a warning when given a filename by --stdin-filename in excluded files list if warnIgnored is false", async () => { eslint = new FlatESLint({ - ignorePath: getFixturePath(".eslintignore"), cwd: getFixturePath(".."), - overrideConfigFile: "fixtures/eslint.config.js" + overrideConfigFile: "fixtures/eslint.config_with_ignores.js" }); const options = { filePath: "fixtures/passing.js", @@ -320,9 +317,8 @@ describe("FlatESLint", () => { it("should suppress excluded file warnings by default", async () => { eslint = new FlatESLint({ - ignorePath: getFixturePath(".eslintignore"), cwd: getFixturePath(".."), - overrideConfigFile: "fixtures/eslint.config.js" + overrideConfigFile: "fixtures/eslint.config_with_ignores.js" }); const options = { filePath: "fixtures/passing.js" }; const results = await eslint.lintText("var bar = foo;", options); @@ -333,10 +329,9 @@ describe("FlatESLint", () => { it("should return a message when given a filename by --stdin-filename in excluded files list and ignore is off", async () => { eslint = new FlatESLint({ - ignorePath: "fixtures/.eslintignore", cwd: getFixturePath(".."), ignore: false, - overrideConfigFile: true, + overrideConfigFile: "fixtures/eslint.config_with_ignores.js", overrideConfig: { rules: { "no-undef": 2 @@ -985,7 +980,7 @@ describe("FlatESLint", () => { it("should throw an error when given a directory with all eslint excluded files in the directory", async () => { eslint = new FlatESLint({ - ignorePath: getFixturePath(".eslintignore") + overrideConfigFile: getFixturePath("eslint.config_with_ignores.js") }); await assert.rejects(async () => { @@ -995,7 +990,7 @@ describe("FlatESLint", () => { it("should throw an error when all given files are ignored", async () => { eslint = new FlatESLint({ - ignorePath: getFixturePath(".eslintignore") + overrideConfigFile: getFixturePath("eslint.config_with_ignores.js") }); await assert.rejects(async () => { @@ -1005,7 +1000,7 @@ describe("FlatESLint", () => { it("should throw an error when all given files are ignored even with a `./` prefix", async () => { eslint = new FlatESLint({ - ignorePath: getFixturePath(".eslintignore") + overrideConfigFile: getFixturePath("eslint.config_with_ignores.js") }); await assert.rejects(async () => { @@ -1014,9 +1009,8 @@ describe("FlatESLint", () => { }); // https://github.com/eslint/eslint/issues/3788 - it("should ignore one-level down node_modules when ignore file has 'node_modules/' in it", async () => { + it("should ignore one-level down node_modules by default", async () => { eslint = new FlatESLint({ - ignorePath: getFixturePath("cli-engine", "nested_node_modules", ".eslintignore"), overrideConfigFile: true, overrideConfig: { rules: { @@ -1036,10 +1030,9 @@ describe("FlatESLint", () => { }); // https://github.com/eslint/eslint/issues/3812 - it("should ignore all files and throw an error when fixtures/ is in ignore file", async () => { + it("should ignore all files and throw an error when **/fixtures/** is in `ignores` in the config file", async () => { eslint = new FlatESLint({ - ignorePath: getFixturePath("cli-engine/.eslintignore2"), - overrideConfigFile: true, + overrideConfigFile: getFixturePath("cli-engine/eslint.config_with_ignores2.js"), overrideConfig: { rules: { quotes: [2, "double"] @@ -1066,7 +1059,7 @@ describe("FlatESLint", () => { it("should return a warning when an explicitly given file is ignored", async () => { eslint = new FlatESLint({ - ignorePath: getFixturePath(".eslintignore"), + overrideConfigFile: "eslint.config_with_ignores.js", cwd: getFixturePath() }); const filePath = getFixturePath("passing.js"); @@ -1087,9 +1080,8 @@ describe("FlatESLint", () => { it("should return two messages when given a file in excluded files list while ignore is off", async () => { eslint = new FlatESLint({ cwd: getFixturePath(), - ignorePath: getFixturePath(".eslintignore"), ignore: false, - overrideConfigFile: true, + overrideConfigFile: getFixturePath("eslint.config_with_ignores.js"), overrideConfig: { rules: { "no-undef": 2 @@ -3138,7 +3130,7 @@ describe("FlatESLint", () => { describe("isPathIgnored", () => { it("should check if the given path is ignored", async () => { const engine = new FlatESLint({ - ignorePath: getFixturePath(".eslintignore2"), + overrideConfigFile: getFixturePath("eslint.config_with_ignores2.js"), cwd: getFixturePath() }); @@ -3149,7 +3141,7 @@ describe("FlatESLint", () => { it("should return false if ignoring is disabled", async () => { const engine = new FlatESLint({ ignore: false, - ignorePath: getFixturePath(".eslintignore2"), + overrideConfigFile: getFixturePath("eslint.config_with_ignores2.js"), cwd: getFixturePath() }); @@ -3188,7 +3180,7 @@ describe("FlatESLint", () => { const engine = new FlatESLint({ cwd, overrideConfigFile: true, - ignorePatterns: "!/node_modules/package" + ignorePatterns: "!node_modules/package/**" }); const result = await engine.isPathIgnored(getFixturePath("ignored-paths", "node_modules", "package", "file.js")); @@ -3201,7 +3193,9 @@ describe("FlatESLint", () => { const engine = new FlatESLint({ cwd, overrideConfigFile: true, - ignorePath: getFixturePath("ignored-paths", ".eslintignoreWithUnignoredDefaults") + overrideConfig: { + ignores: ["!node_modules/package/**"] + } }); assert(!await engine.isPathIgnored(getFixturePath("ignored-paths", "node_modules", "package", "file.js"))); @@ -3228,53 +3222,21 @@ describe("FlatESLint", () => { assert(!await engine.isPathIgnored(`${getFixturePath("ignored-paths", "foo")}/../unignored.js`)); }); - it("should ignore /node_modules/ relative to .eslintignore when loaded", async () => { - const cwd = getFixturePath("ignored-paths"); - const engine = new FlatESLint({ ignorePath: getFixturePath("ignored-paths", ".eslintignore"), cwd }); - - assert(await engine.isPathIgnored(getFixturePath("ignored-paths", "node_modules", "existing.js"))); - assert(await engine.isPathIgnored(getFixturePath("ignored-paths", "foo", "node_modules", "existing.js"))); - }); - - it("should ignore /node_modules/ relative to cwd without an .eslintignore", async () => { + it("should ignore /node_modules/ relative to cwd without any configured ignore patterns", async () => { const cwd = getFixturePath("ignored-paths", "no-ignore-file"); const engine = new FlatESLint({ cwd }); assert(await engine.isPathIgnored(getFixturePath("ignored-paths", "no-ignore-file", "node_modules", "existing.js"))); assert(await engine.isPathIgnored(getFixturePath("ignored-paths", "no-ignore-file", "foo", "node_modules", "existing.js"))); }); - }); - - describe("with no .eslintignore file", () => { - it("should not travel to parent directories to find .eslintignore when it's missing and cwd is provided", async () => { - const cwd = getFixturePath("ignored-paths", "configurations"); - const engine = new FlatESLint({ cwd }); - - // a .eslintignore in parent directories includes `*.js`, but don't load it. - assert(!await engine.isPathIgnored("foo.js")); - assert(await engine.isPathIgnored("node_modules/foo.js")); - }); - it("should return false for files outside of the cwd (with no ignore file provided)", async () => { - - // Default ignore patterns should not inadvertently ignore files in parent directories + it("should not inadvertently ignore all files in parent directories", async () => { const engine = new FlatESLint({ cwd: getFixturePath("ignored-paths", "no-ignore-file") }); assert(!await engine.isPathIgnored(getFixturePath("ignored-paths", "undef.js"))); }); }); - describe("with .eslintignore file or package.json file", () => { - it("should load .eslintignore from cwd when explicitly passed", async () => { - const cwd = getFixturePath("ignored-paths"); - const engine = new FlatESLint({ cwd }); - - // `${cwd}/.eslintignore` includes `sampleignorepattern`. - assert(await engine.isPathIgnored("sampleignorepattern")); - }); - - }); - describe("with ignorePatterns option", () => { it("should accept a string for options.ignorePatterns", async () => { const cwd = getFixturePath("ignored-paths", "ignore-pattern"); @@ -3309,16 +3271,20 @@ describe("FlatESLint", () => { it("should return true for file matching an ignore pattern exactly", async () => { const cwd = getFixturePath("ignored-paths"); - const engine = new FlatESLint({ ignorePatterns: ["undef.js"], cwd }); + const engine = new FlatESLint({ + ignorePatterns: ["undef.js"], + cwd, + overrideConfigFile: true + }); assert(await engine.isPathIgnored(getFixturePath("ignored-paths", "undef.js"))); }); - it("should return false for file in subfolder of cwd matching an ignore pattern with leading '/'", async () => { + it("should return false for file in subfolder of cwd matching an ignore pattern with a base filename", async () => { const cwd = getFixturePath("ignored-paths"); const filePath = getFixturePath("ignored-paths", "subdir", "undef.js"); const engine = new FlatESLint({ - ignorePatterns: ["/undef.js"], + ignorePatterns: ["undef.js"], overrideConfigFile: true, cwd }); @@ -3333,11 +3299,11 @@ describe("FlatESLint", () => { assert(await engine.isPathIgnored(getFixturePath("ignored-paths", "ignore-pattern", "ignore-me.txt"))); }); - it("should return true for file matching a grandchild of an ignore pattern", async () => { + it("should return true for file matching a grandchild of a directory when the pattern is directory/**", async () => { const cwd = getFixturePath("ignored-paths"); - const engine = new FlatESLint({ ignorePatterns: ["ignore-pattern"], cwd }); + const engine = new FlatESLint({ ignorePatterns: ["ignore-pattern/**"], cwd }); - assert(await engine.isPathIgnored(getFixturePath("ignored-paths", "ignore-pattern", "subdir", "ignore-me.txt"))); + assert(await engine.isPathIgnored(getFixturePath("ignored-paths", "ignore-pattern", "subdir", "ignore-me.js"))); }); it("should return false for file not matching any ignore pattern", async () => { @@ -3364,146 +3330,11 @@ describe("FlatESLint", () => { }); }); - describe("with ignorePath option", () => { - it("initialization with ignorePath should work when cwd is a parent directory", async () => { - const cwd = getFixturePath("ignored-paths"); - const ignorePath = getFixturePath("ignored-paths", "custom-name", "ignore-file"); - const engine = new FlatESLint({ ignorePath, cwd }); - - assert(await engine.isPathIgnored("custom-name/foo.js")); - }); - - it("initialization with ignorePath should work when the file is in the cwd", async () => { - const cwd = getFixturePath("ignored-paths", "custom-name"); - const ignorePath = getFixturePath("ignored-paths", "custom-name", "ignore-file"); - const engine = new FlatESLint({ ignorePath, cwd }); - - assert(await engine.isPathIgnored("foo.js")); - }); - - it("initialization with ignorePath should work when cwd is a subdirectory", async () => { - const cwd = getFixturePath("ignored-paths", "custom-name", "subdirectory"); - const ignorePath = getFixturePath("ignored-paths", "custom-name", "ignore-file"); - const engine = new FlatESLint({ ignorePath, cwd }); - - assert(await engine.isPathIgnored("../custom-name/foo.js")); - }); - - it("missing ignore file should throw error", done => { - const cwd = getFixturePath("ignored-paths"); - const ignorePath = getFixturePath("ignored-paths", "not-a-directory", ".foobaz"); - const engine = new FlatESLint({ ignorePath, cwd }); - - engine.isPathIgnored("foo.js").then(() => { - assert.fail("missing file should not succeed"); - }).catch(error => { - assert(/Cannot read ignore file/u.test(error)); - done(); - }); - }); - - it("should return false for files outside of ignorePath's directory", async () => { - const cwd = getFixturePath("ignored-paths"); - const ignorePath = getFixturePath("ignored-paths", "custom-name", "ignore-file"); - const engine = new FlatESLint({ ignorePath, cwd }); - - assert(!await engine.isPathIgnored(getFixturePath("ignored-paths", "undef.js"))); - }); - - it("should resolve relative paths from CWD", async () => { - const cwd = getFixturePath("ignored-paths", "subdir"); - - // /undef.js in ignore file - const ignorePath = getFixturePath("ignored-paths", ".eslintignoreForDifferentCwd"); - const engine = new FlatESLint({ ignorePath, cwd, overrideConfigFile: true }); - - assert(await engine.isPathIgnored(getFixturePath("ignored-paths", "subdir/undef.js")), "subdir/undef.js should be ignored"); - assert(!await engine.isPathIgnored(getFixturePath("ignored-paths", "subdir/subdir/undef.js")), "subdir/subdir/undef.js should not be ignored"); - }); - - it("should resolve relative paths from CWD when it's in a child directory", async () => { - const cwd = getFixturePath("ignored-paths"); - const ignorePath = getFixturePath("ignored-paths", "subdir/.eslintignoreInChildDir"); - const engine = new FlatESLint({ ignorePath, cwd }); - - assert(!await engine.isPathIgnored(getFixturePath("ignored-paths", "subdir/undef.js"))); - assert(await engine.isPathIgnored(getFixturePath("ignored-paths", "undef.js"))); - assert(await engine.isPathIgnored(getFixturePath("ignored-paths", "foo.js"))); - assert(await engine.isPathIgnored(getFixturePath("ignored-paths", "subdir/foo.js"))); - - assert(await engine.isPathIgnored(getFixturePath("ignored-paths", "node_modules/bar.js"))); - }); - - it("should resolve relative paths from CWD when it contains negated globs", async () => { - const cwd = getFixturePath("ignored-paths"); - const ignorePath = getFixturePath("ignored-paths", "subdir/.eslintignoreInChildDir"); - const engine = new FlatESLint({ - ignorePath, - cwd, - overrideConfig: { - files: ["**/*.txt"] - } - }); - - assert(await engine.isPathIgnored("subdir/blah.txt"), "subdir/blah.txt should be ignore"); - assert(await engine.isPathIgnored("blah.txt"), "blah.txt should be ignored"); - assert(await engine.isPathIgnored("subdir/bar.txt"), "subdir/bar.txt should be ignored"); - assert(!await engine.isPathIgnored("bar.txt"), "bar.txt should not be ignored"); - assert(!await engine.isPathIgnored("baz.txt"), "baz.txt should not be ignored"); - assert(!await engine.isPathIgnored("subdir/baz.txt"), "subdir/baz.txt should not be ignored"); - }); - - it("should resolve default ignore patterns from the CWD even when the ignorePath is in a subdirectory", async () => { - const cwd = getFixturePath("ignored-paths"); - const ignorePath = getFixturePath("ignored-paths", "subdir/.eslintignoreInChildDir"); - const engine = new FlatESLint({ ignorePath, cwd }); - - assert(await engine.isPathIgnored("node_modules/blah.js")); - }); - - it("should resolve default ignore patterns from the CWD even when the ignorePath is in a parent directory", async () => { - const cwd = getFixturePath("ignored-paths", "subdir"); - const ignorePath = getFixturePath("ignored-paths", ".eslintignoreForDifferentCwd"); - const engine = new FlatESLint({ ignorePath, cwd }); - - assert(await engine.isPathIgnored("node_modules/blah.js")); - }); - - it("should handle .eslintignore which contains CRLF correctly.", async () => { - const ignoreFileContent = fs.readFileSync(getFixturePath("ignored-paths", "crlf/.eslintignore"), "utf8"); - - assert(ignoreFileContent.includes("\r"), "crlf/.eslintignore should contains CR.", "Ignore file must have CRLF for test to pass."); - const cwd = getFixturePath("ignored-paths"); - const ignorePath = getFixturePath("ignored-paths", "crlf/.eslintignore"); - const engine = new FlatESLint({ ignorePath, cwd }); - - assert(await engine.isPathIgnored(getFixturePath("ignored-paths", "crlf/hide1/a.js"))); - assert(await engine.isPathIgnored(getFixturePath("ignored-paths", "crlf/hide2/a.js"))); - assert(!await engine.isPathIgnored(getFixturePath("ignored-paths", "crlf/hide3/a.js"))); - }); - - it("should ignore a non-negated pattern", async () => { - const cwd = getFixturePath("ignored-paths"); - const ignorePath = getFixturePath("ignored-paths", ".eslintignoreWithNegation"); - const engine = new FlatESLint({ ignorePath, cwd }); - - assert(await engine.isPathIgnored(getFixturePath("ignored-paths", "negation", "ignore.js"))); - }); - - it("should not ignore a negated pattern", async () => { - const cwd = getFixturePath("ignored-paths"); - const ignorePath = getFixturePath("ignored-paths", ".eslintignoreWithNegation"); - const engine = new FlatESLint({ ignorePath, cwd }); - - assert(!await engine.isPathIgnored(getFixturePath("ignored-paths", "negation", "unignore.js"))); - }); - }); - - describe("with ignorePath option and ignorePatterns option", () => { + describe("with config ignores ignorePatterns option", () => { it("should return false for ignored file when unignored with ignore pattern", async () => { const cwd = getFixturePath("ignored-paths"); const engine = new FlatESLint({ - ignorePath: getFixturePath("ignored-paths", ".eslintignoreForNegationTest"), + overrideConfigFile: getFixturePath("eslint.config_with_ignores2.js"), ignorePatterns: ["!undef.js"], cwd }); @@ -3703,8 +3534,7 @@ describe("FlatESLint", () => { it("should return 0 error or warning messages even when the file has warnings", async () => { const engine = new FlatESLint({ - overrideConfigFile: true, - ignorePath: path.join(fixtureDir, ".eslintignore"), + overrideConfigFile: getFixturePath("eslint.config_with_ignores.js"), cwd: path.join(fixtureDir, "..") }); const options = { @@ -4231,14 +4061,13 @@ describe("FlatESLint", () => { }); }); - xdescribe(".eslintignore can re-ignore files that are unignored by ignorePatterns.", () => { + xdescribe("ignore pattern can re-ignore files that are unignored by a previous pattern.", () => { const { prepare, cleanup, getPath } = createCustomTeardown({ cwd: root, files: { "eslint.config.js": `module.exports = ${JSON.stringify({ - ignores: ["!.*"] + ignores: ["!.*", ".foo*"] })}`, - ".eslintignore": ".foo*", ".foo.js": "", ".bar.js": "" } @@ -4272,14 +4101,13 @@ describe("FlatESLint", () => { }); }); - xdescribe(".eslintignore can unignore files that are ignored by ignorePatterns.", () => { + xdescribe("ignore pattern can unignore files that are ignored by a previous pattern.", () => { const { prepare, cleanup, getPath } = createCustomTeardown({ cwd: root, files: { "eslint.config.js": `module.exports = ${JSON.stringify({ - ignores: ["**/*.js"] + ignores: ["**/*.js", "!foo.js"] })}`, - ".eslintignore": "!foo.js", "foo.js": "", "bar.js": "" } diff --git a/tests/lib/options.js b/tests/lib/options.js index 4d3507a4764..d8f795b78a2 100644 --- a/tests/lib/options.js +++ b/tests/lib/options.js @@ -124,14 +124,6 @@ describe("options", () => { }); }); - describe("--ignore-path", () => { - it("should return a string for .ignorePath when passed", () => { - const currentOptions = options.parse("--ignore-path .gitignore"); - - assert.strictEqual(currentOptions.ignorePath, ".gitignore"); - }); - }); - describe("--ignore-pattern", () => { it("should return a string array for .ignorePattern when passed", () => { const currentOptions = options.parse("--ignore-pattern *.js"); @@ -371,6 +363,14 @@ describe("options", () => { }); }); + describe("--ignore-path", () => { + it("should return a string for .ignorePath when passed", () => { + const currentOptions = eslintrcOptions.parse("--ignore-path .gitignore"); + + assert.strictEqual(currentOptions.ignorePath, ".gitignore"); + }); + }); + describe("--parser", () => { it("should return a string for --parser when passed", () => { const currentOptions = eslintrcOptions.parse("--parser test");