8000 fix: skip processor code blocks that match only universal patterns (#… · eslint/eslint@f6534d1 · GitHub
[go: up one dir, main page]

Skip to content

Commit f6534d1

Browse files
authored
fix: skip processor code blocks that match only universal patterns (#18507)
Fixes #18493 Closes #15949
1 parent 7226ebd commit f6534d1

File tree

3 files changed

+214
-2
lines changed

3 files changed

+214
-2
lines changed

docs/src/use/configure/plugins.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,41 @@ export default [
213213
];
214214
```
215215

216-
ESLint only lints named code blocks when they are JavaScript files or if they match a `files` entry in a config object. Be sure to add a config object with a matching `files` entry if you want to lint non-JavaScript named code blocks.
216+
ESLint only lints named code blocks when they are JavaScript files or if they match a `files` entry in a config object. Be sure to add a config object with a matching `files` entry if you want to lint non-JavaScript named code blocks. Also note that [global ignores](./ignore) apply to named code blocks as well.
217+
218+
```js
219+
// eslint.config.js
220+
import markdown from "eslint-plugin-markdown";
221+
222+
export default [
223+
224+
// applies to Markdown files
225+
{
226+
files: ["**/*.md"],
227+
plugins: {
228+
markdown
229+
},
230+
processor: "markdown/markdown"
231+
},
232+
233+
// applies to all .jsx files, including jsx blocks inside of Markdown files
234+
{
235+
files: ["**/*.jsx"],
236+
languageOptions: {
237+
parserOptions: {
238+
ecmaFeatures: {
239+
jsx: true
240+
}
241+
}
242+
}
243+
},
244+
245+
// ignore jsx blocks inside of test.md files
246+
{
247+
ignores: ["**/test.md/*.jsx"]
248+
}
249+
];
250+
```
217251

218252
## Common Problems
219253

lib/eslint/eslint.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ function verifyText({
509509
* @returns {boolean} `true` if the linter should adopt the code block.
510510
*/
511511
filterCodeBlock(blockFilename) {
512-
return configs.isExplicitMatch(blockFilename);
512+
return configs.getConfig(blockFilename) !== void 0;
513513
}
514514
}
515515
);

tests/lib/eslint/eslint.js

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ describe("ESLint", () => {
6767
}
6868
};
6969
const examplePreprocessorName = "eslint-plugin-processor";
70+
const patternProcessor = require("../../fixtures/processors/pattern-processor");
71+
const exampleMarkdownPlugin = {
72+
processors: {
73+
markdown: patternProcessor.defineProcessor(/```(\w+)\n(.+?)\n```(?:\n|$)/gsu)
74+
}
75+
};
7076
const originalDir = process.cwd();
7177
const fixtureDir = path.resolve(fs.realpathSync(os.tmpdir()), "eslint/fixtures");
7278

@@ -3761,6 +3767,178 @@ describe("ESLint", () => {
37613767
assert(!Object.hasOwn(results[0], "output"));
37623768
});
37633769
});
3770+
3771+
describe("matching and ignoring code blocks", () => {
3772+
const pluginConfig = {
3773+
files: ["**/*.md"],
3774+
plugins: {
3775+
markdown: exampleMarkdownPlugin
3776+
},
3777+
processor: "markdown/markdown"
3778+
};
3779+
const text = unIndent`
3780+
\`\`\`js
3781+
foo_js
3782+
\`\`\`
3783+
3784+
\`\`\`ts
3785+
foo_ts
3786+
\`\`\`
3787+
3788+
\`\`\`cjs
3789+
foo_cjs
3790+
\`\`\`
3791+
3792+
\`\`\`mjs
3793+
foo_mjs
3794+
\`\`\`
3795+
`;
3796+
3797+
it("should by default lint only .js, .mjs, and .cjs virtual files", async () => {
3798+
eslint = new ESLint({
3799+
overrideConfigFile: true,
3800+
overrideConfig: [
3801+
pluginConfig,
3802+
{
3803+
rules: {
3804+
"no-undef": 2
3805+
}
3806+
}
3807+
]
3808+
});
3809+
const [result] = await eslint.lintText(text, { filePath: "foo.md" });
3810+
3811+
assert.strictEqual(result.messages.length, 3);
3812+
assert.strictEqual(result.messages[0].ruleId, "no-undef");
3813+
assert.match(result.messages[0].message, /foo_js/u);
3814+
assert.strictEqual(result.messages[0].line, 2);
3815+
assert.strictEqual(result.messages[1].ruleId, "no-undef");
3816+
assert.match(result.messages[1].message, /foo_cjs/u);
3817+
assert.strictEqual(result.messages[1].line, 10);
3818+
assert.strictEqual(result.messages[2].ruleId, "no-undef");
3819+
assert.match(result.messages[2].message, /foo_mjs/u);
3820+
assert.strictEqual(result.messages[2].line, 14);
3821+
});
3822+
3823+
it("should lint additional virtual files that match non-universal patterns", async () => {
3824+
eslint = new ESLint({
3825+
overrideConfigFile: true,
3826+
overrideConfig: [
3827+
pluginConfig,
3828+
{
3829+
rules: {
3830+
"no-undef": 2
3831+
}
3832+
},
3833+
{
3834+
files: ["**/*.ts"]
3835+
}
3836+
]
3837+
});
3838+
const [result] = await eslint.lintText(text, { filePath: "foo.md" });
3839+
3840+
assert.strictEqual(result.messages.length, 4);
3841+
assert.strictEqual(result.messages[0].ruleId, "no-undef");
3842+
assert.match(result.messages[0].message, /foo_js/u);
3843+
assert.strictEqual(result.messages[0].line, 2);
3844+
assert.strictEqual(result.messages[1].ruleId, "no-undef");
3845+
assert.match(result.messages[1].message, /foo_ts/u);
3846+
assert.strictEqual(result.messages[1].line, 6);
3847+
assert.strictEqual(result.messages[2].ruleId, "no-undef");
3848+
assert.match(result.messages[2].message, /foo_cjs/u);
3849+
assert.strictEqual(result.messages[2].line, 10);
3850+
assert.strictEqual(result.messages[3].ruleId, "no-undef");
3851+
assert.match(result.messages[3].message, /foo_mjs/u);
3852+
assert.strictEqual(result.messages[3].line, 14);
3853+
});
3854+
3855+
// https://github.com/eslint/eslint/issues/18493
3856+
it("should silently skip virtual files that match only universal patterns", async () => {
3857+
eslint = new ESLint({
3858+
overrideConfigFile: true,
3859+
overrideConfig: [
3860+
pluginConfig,
3861+
{
3862+
files: ["**/*"],
3863+
rules: {
3864+
"no-undef": 2
3865+
}
3866+
}
3867+
]
3868+
});
3869+
const [result] = await eslint.lintText(text, { filePath: "foo.md" });
3870+
3871+
assert.strictEqual(result.messages.length, 3);
3872+
assert.strictEqual(result.messages[0].ruleId, "no-undef");
3873+
assert.match(result.messages[0].message, /foo_js/u);
3874+
assert.strictEqual(result.messages[0].line, 2);
3875+
assert.strictEqual(result.messages[1].ruleId, "no-undef");
3876+
assert.match(result.messages[1].message, /foo_cjs/u);
3877+
assert.strictEqual(result.messages[1].line, 10);
3878+
assert.strictEqual(result.messages[2].ruleId, "no-undef");
3879+
assert.match(result.messages[2].message, /foo_mjs/u);
3880+
assert.strictEqual(result.messages[2].line, 14);
3881+
});
3882+
3883+
it("should silently skip virtual files that are ignored by global ignores", async () => {
3884+
eslint = new ESLint({
3885+
overrideConfigFile: true,
3886+
overrideConfig: [
3887+
pluginConfig,
3888+
{
3889+
rules: {
3890+
"no-undef": 2
3891+
}
3892+
},
3893+
{
3894+
ignores: ["**/*.cjs"]
3895+
}
3896+
]
3897+
});
3898+
const [result] = await eslint.lintText(text, { filePath: "foo.md" });
3899+
3900+
assert.strictEqual(result.messages.length, 2);
3901+
assert.strictEqual(result.messages[0].ruleId, "no-undef");
3902+
assert.match(result.messages[0].message, /foo_js/u);
3903+
assert.strictEqual(result.messages[0].line, 2);
3904+
assert.strictEqual(result.messages[1].ruleId, "no-undef");
3905+
assert.match(result.messages[1].message, /foo_mjs/u);
3906+
assert.strictEqual(result.messages[1].line, 14);
3907+
});
3908+
3909+
// https://github.com/eslint/eslint/issues/15949
3910+
it("should silently skip virtual files that are ignored by global ignores even if they match non-universal patterns", async () => {
3911+
eslint = new ESLint({
3912+
overrideConfigFile: true,
3913+
overrideConfig: [
3914+
pluginConfig,
3915+
{
3916+
rules: {
3917+
"no-undef": 2
3918+
}
3919+
},
3920+
{
3921+
files: ["**/*.ts"]
3922+
},
3923+
{
3924+
ignores: ["**/*.md/*.ts"]
3925+
}
3926+
]
3927+
});
3928+
const [result] = await eslint.lintText(text, { filePath: "foo.md" });
3929+
3930+
assert.strictEqual(result.messages.length, 3);
3931+
assert.strictEqual(result.messages[0].ruleId, "no-undef");
3932+
assert.match(result.messages[0].message, /foo_js/u);
3933+
assert.strictEqual(result.messages[0].line, 2);
3934+
assert.strictEqual(result.messages[1].ruleId, "no-undef");
3935+
assert.match(result.messages[1].message, /foo_cjs/u);
3936+
assert.strictEqual(result.messages[1].line, 10);
3937+
assert.strictEqual(result.messages[2].ruleId, "no-undef");
3938+
assert.match(result.messages[2].message, /foo_mjs/u);
3939+
assert.strictEqual(result.messages[2].line, 14);
3940+
});
3941+
});
37643942
});
37653943

37663944
describe("Patterns which match no file should throw errors.", () => {

0 commit comments

Comments
 (0)
0