Skip to content

Commit 2dec349

Browse files
authored
fix: skip processor code blocks that match only universal patterns (#18880)
* fix: skip processor code blocks that match only universal patterns * enable CI
1 parent 6a5add4 commit 2dec349

File tree

5 files changed

+218
-3
lines changed

5 files changed

+218
-3
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
name: CI
22
on:
33
push:
4-
branches: [main, v8.x]
4+
branches: [main, v8.x-dev]
55
pull_request:
6-
branches: [main, v8.x]
6+
branches: [main, v8.x-dev]
77

88
permissions:
99
contents: read

docs/src/use/configure/configuration-files-new.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,42 @@ export default [
529529
];
530530
```
531531

532+
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](#globally-ignoring-files-with-ignores) apply to named code blocks as well.
533+
534+
```js
535+
// eslint.config.js
536+
import markdown from "eslint-plugin-markdown";
537+
538+
export default [
539+
540+
// applies to Markdown files
541+
{
542+
files: ["**/*.md"],
543+
plugins: {
544+
markdown
545+
},
546+
processor: "markdown/markdown"
547+
},
548+
549+
// applies to all .jsx files, including jsx blocks inside of Markdown files
550+
{
551+
files: ["**/*.jsx"],
552+
languageOptions: {
553+
parserOptions: {
554+
ecmaFeatures: {
555+
jsx: true
556+
}
557+
}
558+
}
559+
},
560+
561+
// ignore jsx blocks inside of test.md files
562+
{
563+
ignores: ["**/test.md/*.jsx"]
564+
}
565+
];
566+
```
567+
532568
### Configuring rules
533569

534570
You can configure any number of rules in a configuration object by add a `rules` property containing an object with your rule configurations. The names in this object are the names of the rules and the values are the configurations for each of those rules. Here's an example:

lib/eslint/flat-eslint.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ function verifyText({
489489
* @returns {boolean} `true` if the linter should adopt the code block.
490490
*/
491491
filterCodeBlock(blockFilename) {
492-
return configs.isExplicitMatch(blockFilename);
492+
return configs.getConfig(blockFilename) !== void 0;
493493
}
494494
}
495495
);

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@
104104
"devDependencies": {
105105
"@babel/core": "^7.4.3",
106106
"@babel/preset-env": "^7.4.3",
107+
"@sinonjs/fake-timers": "11.2.2",
107108
"@wdio/browser-runner": "^8.14.6",
108109
"@wdio/cli": "^8.14.6",
109110
"@wdio/concise-reporter": "^8.14.0",

tests/lib/eslint/flat-eslint.js

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

@@ -3590,6 +3596,178 @@ describe("FlatESLint", () => {
35903596
assert(!Object.prototype.hasOwnProperty.call(results[0], "output"));
35913597
});
35923598
});
3599+
3600+
describe("matching and ignoring code blocks", () => {
3601+
const pluginConfig = {
3602+
files: ["**/*.md"],
3603+
plugins: {
3604+
markdown: exampleMarkdownPlugin
3605+
},
3606+
processor: "markdown/markdown"
3607+
};
3608+
const text = unIndent`
3609+
\`\`\`js
3610+
foo_js
3611+
\`\`\`
3612+
3613+
\`\`\`ts
3614+
foo_ts
3615+
\`\`\`
3616+
3617+
\`\`\`cjs
3618+
foo_cjs
3619+
\`\`\`
3620+
3621+
\`\`\`mjs
3622+
foo_mjs
3623+
\`\`\`
3624+
`;
3625+
3626+
it("should by default lint only .js, .mjs, and .cjs virtual files", async () => {
3627+
eslint = new FlatESLint({
3628+
overrideConfigFile: true,
3629+
overrideConfig: [
3630+
pluginConfig,
3631+
{
3632+
rules: {
3633+
"no-undef": 2
3634+
}
3635+
}
3636+
]
3637+
});
3638+
const [result] = await eslint.lintText(text, { filePath: "foo.md" });
3639+
3640+
assert.strictEqual(result.messages.length, 3);
3641+
assert.strictEqual(result.messages[0].ruleId, "no-undef");
3642+
assert.match(result.messages[0].message, /foo_js/u);
3643+
assert.strictEqual(result.messages[0].line, 2);
3644+
assert.strictEqual(result.messages[1].ruleId, "no-undef");
3645+
assert.match(result.messages[1].message, /foo_cjs/u);
3646+
assert.strictEqual(result.messages[1].line, 10);
3647+
assert.strictEqual(result.messages[2].ruleId, "no-undef");
3648+
assert.match(result.messages[2].message, /foo_mjs/u);
3649+
assert.strictEqual(result.messages[2].line, 14);
3650+
});
3651+
3652+
it("should lint additional virtual files that match non-universal patterns", async () => {
3653+
eslint = new FlatESLint({
3654+
overrideConfigFile: true,
3655+
overrideConfig: [
3656+
pluginConfig,
3657+
{
3658+
rules: {
3659+
"no-undef": 2
3660+
}
3661+
},
3662+
{
3663+
files: ["**/*.ts"]
3664+
}
3665+
]
3666+
});
3667+
const [result] = await eslint.lintText(text, { filePath: "foo.md" });
3668+
3669+
assert.strictEqual(result.messages.length, 4);
3670+
assert.strictEqual(result.messages[0].ruleId, "no-undef");
3671+
assert.match(result.messages[0].message, /foo_js/u);
3672+
assert.strictEqual(result.messages[0].line, 2);
3673+
assert.strictEqual(result.messages[1].ruleId, "no-undef");
3674+
assert.match(result.messages[1].message, /foo_ts/u);
3675+
assert.strictEqual(result.messages[1].line, 6);
3676+
assert.strictEqual(result.messages[2].ruleId, "no-undef");
3677+
assert.match(result.messages[2].message, /foo_cjs/u);
3678+
assert.strictEqual(result.messages[2].line, 10);
3679+
assert.strictEqual(result.messages[3].ruleId, "no-undef");
3680+
assert.match(result.messages[3].message, /foo_mjs/u);
3681+
assert.strictEqual(result.messages[3].line, 14);
3682+
});
3683+
3684+
// https://github.com/eslint/eslint/issues/18493
3685+
it("should silently skip virtual files that match only universal patterns", async () => {
3686+
eslint = new FlatESLint({
3687+
overrideConfigFile: true,
3688+
overrideConfig: [
3689+
pluginConfig,
3690+
{
3691+
files: ["**/*"],
3692+
rules: {
3693+
"no-undef": 2
3694+
}
3695+
}
3696+
]
3697+
});
3698+
const [result] = await eslint.lintText(text, { filePath: "foo.md" });
3699+
3700+
assert.strictEqual(result.messages.length, 3);
3701+
assert.strictEqual(result.messages[0].ruleId, "no-undef");
3702+
assert.match(result.messages[0].message, /foo_js/u);
3703+
assert.strictEqual(result.messages[0].line, 2);
3704+
assert.strictEqual(result.messages[1].ruleId, "no-undef");
3705+
assert.match(result.messages[1].message, /foo_cjs/u);
3706+
assert.strictEqual(result.messages[1].line, 10);
3707+
assert.strictEqual(result.messages[2].ruleId, "no-undef");
3708+
assert.match(result.messages[2].message, /foo_mjs/u);
3709+
assert.strictEqual(result.messages[2].line, 14);
3710+
});
3711+
3712+
it("should silently skip virtual files that are ignored by global ignores", async () => {
3713+
eslint = new FlatESLint({
3714+
overrideConfigFile: true,
3715+
overrideConfig: [
3716+
pluginConfig,
3717+
{
3718+
rules: {
3719+
"no-undef": 2
3720+
}
3721+
},
3722+
{
3723+
ignores: ["**/*.cjs"]
3724+
}
3725+
]
3726+
});
3727+
const [result] = await eslint.lintText(text, { filePath: "foo.md" });
3728+
3729+
assert.strictEqual(result.messages.length, 2);
3730+
assert.strictEqual(result.messages[0].ruleId, "no-undef");
3731+
assert.match(result.messages[0].message, /foo_js/u);
3732+
assert.strictEqual(result.messages[0].line, 2);
3733+
assert.strictEqual(result.messages[1].ruleId, "no-undef");
3734+
assert.match(result.messages[1].message, /foo_mjs/u);
3735+
assert.strictEqual(result.messages[1].line, 14);
3736+
});
3737+
3738+
// https://github.com/eslint/eslint/issues/15949
3739+
it("should silently skip virtual files that are ignored by global ignores even if they match non-universal patterns", async () => {
3740+
eslint = new FlatESLint({
3741+
overrideConfigFile: true,
3742+
overrideConfig: [
3743+
pluginConfig,
3744+
{
3745+
rules: {
3746+
"no-undef": 2
3747+
}
3748+
},
3749+
{
3750+
files: ["**/*.ts"]
3751+
},
3752+
{
3753+
ignores: ["**/*.md/*.ts"]
3754+
}
3755+
]
3756+
});
3757+
const [result] = await eslint.lintText(text, { filePath: "foo.md" });
3758+
3759+
assert.strictEqual(result.messages.length, 3);
3760+
assert.strictEqual(result.messages[0].ruleId, "no-undef");
3761+
assert.match(result.messages[0].message, /foo_js/u);
3762+
assert.strictEqual(result.messages[0].line, 2);
3763+
assert.strictEqual(result.messages[1].ruleId, "no-undef");
3764+
assert.match(result.messages[1].message, /foo_cjs/u);
3765+
assert.strictEqual(result.messages[1].line, 10);
3766+
assert.strictEqual(result.messages[2].ruleId, "no-undef");
3767+
assert.match(result.messages[2].message, /foo_mjs/u);
3768+
assert.strictEqual(result.messages[2].line, 14);
3769+
});
3770+
});
35933771
});
35943772

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

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy