diff --git a/docs/src/use/migrate-to-9.0.0.md b/docs/src/use/migrate-to-9.0.0.md index 4b33690da13..5f57a5d01f7 100644 --- a/docs/src/use/migrate-to-9.0.0.md +++ b/docs/src/use/migrate-to-9.0.0.md @@ -30,6 +30,7 @@ The lists below are ordered roughly by the number of users each change is expect * [Stricter `/* exported */` parsing](#exported-parsing) * [`"eslint:recommended"` and `"eslint:all"` strings no longer accepted in flat config](#string-config) * [`varsIgnorePattern` option of `no-unused-vars` no longer applies to catch arguments](#vars-ignore-pattern) +* [`--output-file` now writes a file to disk even with an empty output](#output-file) ### Breaking changes for plugin developers @@ -299,6 +300,14 @@ try { **Related issue(s):** [#17540](https://github.com/eslint/eslint/issues/17540) +## `--output-file` now writes a file to disk even with an empty output + +Prior to ESLint v9.0.0, the `--output-file` flag would skip writing a file to disk if the output was empty. However, in ESLint v9.0.0, `--output-file` now consistently writes a file to disk, even when the output is empty. This update ensures a more consistent and reliable behavior for `--output-file`. + +**To address:** Review your usage of the `--output-file` flag, especially if your processes depend on the file's presence or absence based on output content. If necessary, update your scripts or configurations to accommodate this change. + +**Related Issues(s):** [#17660](https://github.com/eslint/eslint/issues/17660) + ## Removed multiple `context` methods ESLint v9.0.0 removes multiple deprecated methods from the `context` object and moves them onto the `SourceCode` object: diff --git a/lib/cli.js b/lib/cli.js index 5100cb17d40..dce15238347 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -285,25 +285,23 @@ async function printResults(engine, results, format, outputFile, resultsMeta) { const output = await formatter.format(results, resultsMeta); - if (output) { - if (outputFile) { - const filePath = path.resolve(process.cwd(), outputFile); + if (outputFile) { + const filePath = path.resolve(process.cwd(), outputFile); - if (await isDirectory(filePath)) { - log.error("Cannot write to output file path, it is a directory: %s", outputFile); - return false; - } + if (await isDirectory(filePath)) { + log.error("Cannot write to output file path, it is a directory: %s", outputFile); + return false; + } - try { - await mkdir(path.dirname(filePath), { recursive: true }); - await writeFile(filePath, output); - } catch (ex) { - log.error("There was a problem writing the output file:\n%s", ex); - return false; - } - } else { - log.info(output); + try { + await mkdir(path.dirname(filePath), { recursive: true }); + await writeFile(filePath, output); + } catch (ex) { + log.error("There was a problem writing the output file:\n%s", ex); + return false; } + } else if (output) { + log.info(output); } return true; diff --git a/tests/lib/cli.js b/tests/lib/cli.js index 04bb8081ae5..212ce82278c 100644 --- a/tests/lib/cli.js +++ b/tests/lib/cli.js @@ -1006,6 +1006,19 @@ describe("cli", () => { assert.isTrue(log.info.notCalled); }); + // https://github.com/eslint/eslint/issues/17660 + it(`should write the file and create dirs if they don't exist even when output is empty with configType:${configType}`, async () => { + const filePath = getFixturePath("single-quoted.js"); + const code = `${flag} --rule 'quotes: [1, single]' --o tests/output/eslint-output.txt ${filePath}`; + + // TODO: fix this test to: await cli.execute(code, null, useFlatConfig); + await cli.execute(code, "var a = 'b'", useFlatConfig); + + assert.isTrue(fs.existsSync("tests/output/eslint-output.txt")); + assert.strictEqual(fs.readFileSync("tests/output/eslint-output.txt", "utf8"), ""); + assert.isTrue(log.info.notCalled); + }); + it(`should return an error if the path is a directory with configType:${configType}`, async () => { const filePath = getFixturePath("single-quoted.js"); const code = `${flag} --rule 'quotes: [1, double]' --o tests/output ${filePath}`;