Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: improve message for ignored files without a matching config #18404

Merged
merged 1 commit into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 22 additions & 14 deletions lib/eslint/eslint-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -543,10 +543,7 @@ async function findFiles({

// files are added directly to the list
if (stat.isFile()) {
results.push({
filePath,
ignored: !configs.getConfig(filePath)
});
results.push(filePath);
}

// directories need extensions attached
Expand Down Expand Up @@ -605,10 +602,7 @@ async function findFiles({

return [
...results,
...globbyResults.map(filePath => ({
filePath: path.resolve(filePath),
ignored: false
}))
...globbyResults.map(filePath => (path.resolve(filePath)))
];
}

Expand All @@ -630,17 +624,31 @@ function isErrorMessage(message) {
* Returns result with warning by ignore settings
* @param {string} filePath File path of checked code
* @param {string} baseDir Absolute path of base directory
* @param {"ignored"|"external"|"unconfigured"} configStatus A status that determines why the file is ignored
* @returns {LintResult} Result with single warning
* @private
*/
function createIgnoreResult(filePath, baseDir) {
function createIgnoreResult(filePath, baseDir, configStatus) {
let message;
const isInNodeModules = baseDir && path.dirname(path.relative(baseDir, filePath)).split(path.sep).includes("node_modules");

if (isInNodeModules) {
message = "File ignored by default because it is located under the node_modules directory. Use ignore pattern \"!**/node_modules/\" to disable file ignore settings or use \"--no-warn-ignored\" to suppress this warning.";
} else {
message = "File ignored because of a matching ignore pattern. Use \"--no-ignore\" to disable file ignore settings or use \"--no-warn-ignored\" to suppress this warning.";
switch (configStatus) {
case "external":
message = "File ignored because outside of base path.";
break;
case "unconfigured":
message = "File ignored because no matching configuration was supplied.";
break;
default:
{
const isInNodeModules = baseDir && path.dirname(path.relative(baseDir, filePath)).split(path.sep).includes("node_modules");

if (isInNodeModules) {
message = "File ignored by default because it is located under the node_modules directory. Use ignore pattern \"!**/node_modules/\" to disable file ignore settings or use \"--no-warn-ignored\" to suppress this warning.";
} else {
message = "File ignored because of a matching ignore pattern. Use \"--no-ignore\" to disable file ignore settings or use \"--no-warn-ignored\" to suppress this warning.";
}
}
break;
}

return {
Expand Down
20 changes: 12 additions & 8 deletions lib/eslint/eslint.js
Original file line number Diff line number Diff line change
Expand Up @@ -865,22 +865,24 @@ class ESLint {
*/
const results = await Promise.all(

filePaths.map(({ filePath, ignored }) => {
filePaths.map(filePath => {

const config = configs.getConfig(filePath);

/*
* If a filename was entered that matches an ignore
* pattern, then notify the user.
* If a filename was entered that cannot be matched
* to a config, then notify the user.
*/
if (ignored) {
if (!config) {
if (warnIgnored) {
return createIgnoreResult(filePath, cwd);
const configStatus = configs.getConfigStatus(filePath);

return createIgnoreResult(filePath, cwd, configStatus);
}

return void 0;
}

const config = configs.getConfig(filePath);

// Skip if there is cached result.
if (lintResultCache) {
const cachedResult =
Expand Down Expand Up @@ -1029,7 +1031,9 @@ class ESLint {
const shouldWarnIgnored = typeof warnIgnored === "boolean" ? warnIgnored : constructorWarnIgnored;

if (shouldWarnIgnored) {
results.push(createIgnoreResult(resolvedFilename, cwd));
const configStatus = configs.getConfigStatus(resolvedFilename);

results.push(createIgnoreResult(resolvedFilename, cwd, configStatus));
}
} else {

Expand Down
86 changes: 86 additions & 0 deletions tests/lib/eslint/eslint.js
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,52 @@ describe("ESLint", () => {
assert.strictEqual(results[0].suppressedMessages.length, 0);
});

it("should return a warning when given a filename without a matching config by --stdin-filename if warnIgnored is true", async () => {
eslint = new ESLint({
cwd: getFixturePath(".."),
overrideConfigFile: true
});

const options = { filePath: "fixtures/file.ts", warnIgnored: true };
const results = await eslint.lintText("type foo = { bar: string };", options);

assert.strictEqual(results.length, 1);
assert.strictEqual(results[0].filePath, getFixturePath("file.ts"));
assert.strictEqual(results[0].messages[0].severity, 1);
assert.strictEqual(results[0].messages[0].message, "File ignored because no matching configuration was supplied.");
assert.strictEqual(results[0].messages[0].output, void 0);
assert.strictEqual(results[0].errorCount, 0);
assert.strictEqual(results[0].warningCount, 1);
assert.strictEqual(results[0].fatalErrorCount, 0);
assert.strictEqual(results[0].fixableErrorCount, 0);
assert.strictEqual(results[0].fixableWarningCount, 0);
assert.strictEqual(results[0].usedDeprecatedRules.length, 0);
assert.strictEqual(results[0].suppressedMessages.length, 0);
});

it("should return a warning when given a filename outside the base path by --stdin-filename if warnIgnored is true", async () => {
eslint = new ESLint({
cwd: getFixturePath(),
overrideConfigFile: true
});

const options = { filePath: "../file.js", warnIgnored: true };
const results = await eslint.lintText("var bar = foo;", options);

assert.strictEqual(results.length, 1);
assert.strictEqual(results[0].filePath, getFixturePath("../file.js"));
assert.strictEqual(results[0].messages[0].severity, 1);
assert.strictEqual(results[0].messages[0].message, "File ignored because outside of base path.");
assert.strictEqual(results[0].messages[0].output, void 0);
assert.strictEqual(results[0].errorCount, 0);
assert.strictEqual(results[0].warningCount, 1);
assert.strictEqual(results[0].fatalErrorCount, 0);
assert.strictEqual(results[0].fixableErrorCount, 0);
assert.strictEqual(results[0].fixableWarningCount, 0);
assert.strictEqual(results[0].usedDeprecatedRules.length, 0);
assert.strictEqual(results[0].suppressedMessages.length, 0);
});

it("should return a warning when given a filename by --stdin-filename in excluded files list if constructor warnIgnored is false, but lintText warnIgnored is true", async () => {
eslint = new ESLint({
cwd: getFixturePath(".."),
Expand Down Expand Up @@ -1791,6 +1837,46 @@ describe("ESLint", () => {
assert.strictEqual(results[0].suppressedMessages.length, 0);
});

it("should return a warning when an explicitly given file has no matching config", async () => {
eslint = new ESLint({
overrideConfigFile: true,
cwd: getFixturePath()
});
const filePath = getFixturePath("files", "foo.js2");
const results = await eslint.lintFiles([filePath]);

assert.strictEqual(results.length, 1);
assert.strictEqual(results[0].filePath, filePath);
assert.strictEqual(results[0].messages[0].severity, 1);
assert.strictEqual(results[0].messages[0].message, "File ignored because no matching configuration was supplied.");
assert.strictEqual(results[0].errorCount, 0);
assert.strictEqual(results[0].warningCount, 1);
assert.strictEqual(results[0].fatalErrorCount, 0);
assert.strictEqual(results[0].fixableErrorCount, 0);
assert.strictEqual(results[0].fixableWarningCount, 0);
assert.strictEqual(results[0].suppressedMessages.length, 0);
});

it("should return a warning when an explicitly given file is outside the base path", async () => {
eslint = new ESLint({
overrideConfigFile: true,
cwd: getFixturePath("files")
});
const filePath = getFixturePath("passing.js");
const results = await eslint.lintFiles([filePath]);

assert.strictEqual(results.length, 1);
assert.strictEqual(results[0].filePath, filePath);
assert.strictEqual(results[0].messages[0].severity, 1);
assert.strictEqual(results[0].messages[0].message, "File ignored because outside of base path.");
assert.strictEqual(results[0].errorCount, 0);
assert.strictEqual(results[0].warningCount, 1);
assert.strictEqual(results[0].fatalErrorCount, 0);
assert.strictEqual(results[0].fixableErrorCount, 0);
assert.strictEqual(results[0].fixableWarningCount, 0);
assert.strictEqual(results[0].suppressedMessages.length, 0);
});

it("should suppress the warning when an explicitly given file is ignored and warnIgnored is false", async () => {
eslint = new ESLint({
overrideConfigFile: "eslint.config-with-ignores.js",
Expand Down