From c0be008d1c998e4ae712a5fd9d1d1a6543545f7d Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Sat, 30 Nov 2024 20:37:54 +0900 Subject: [PATCH 1/3] feat: changed to prevent crash when used with language plugins --- package.json | 3 +- .../block-mapping-colon-indicator-newline.ts | 2 +- ...lock-mapping-question-indicator-newline.ts | 2 +- src/rules/block-mapping.ts | 2 +- ...block-sequence-hyphen-indicator-newline.ts | 2 +- src/rules/block-sequence.ts | 2 +- src/rules/file-extension.ts | 2 +- src/rules/flow-mapping-curly-newline.ts | 2 +- src/rules/flow-mapping-curly-spacing.ts | 2 +- src/rules/flow-sequence-bracket-newline.ts | 2 +- src/rules/flow-sequence-bracket-spacing.ts | 2 +- src/rules/indent.ts | 2 +- src/rules/key-name-casing.ts | 2 +- src/rules/key-spacing.ts | 2 +- src/rules/no-empty-document.ts | 2 +- src/rules/no-empty-key.ts | 2 +- src/rules/no-empty-mapping-value.ts | 2 +- src/rules/no-empty-sequence-entry.ts | 2 +- src/rules/no-irregular-whitespace.ts | 2 +- src/rules/no-multiple-empty-lines.ts | 2 +- src/rules/no-tab-indent.ts | 2 +- src/rules/no-trailing-zeros.ts | 2 +- src/rules/plain-scalar.ts | 2 +- src/rules/quotes.ts | 2 +- src/rules/require-string-key.ts | 2 +- src/rules/sort-keys.ts | 2 +- src/rules/sort-sequence-values.ts | 2 +- src/rules/spaced-comment.ts | 2 +- src/types.ts | 2 +- src/utils/index.ts | 2 +- .../eslint-plugin/with-json/eslint.config.mjs | 38 +++++++++++++++++++ .../eslint-plugin/with-json/src/test.json | 1 + .../eslint-plugin/with-json/src/test.yml | 1 + tests/src/eslint-plugin.ts | 22 +++++------ tools/new-rule.ts | 2 +- 35 files changed, 83 insertions(+), 42 deletions(-) create mode 100644 tests/fixtures/integrations/eslint-plugin/with-json/eslint.config.mjs create mode 100644 tests/fixtures/integrations/eslint-plugin/with-json/src/test.json create mode 100644 tests/fixtures/integrations/eslint-plugin/with-json/src/test.yml diff --git a/package.json b/package.json index e6b2fc8b..41b3e761 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "@eslint-community/eslint-plugin-eslint-comments": "^4.3.0", "@eslint/eslintrc": "^3.1.0", "@eslint/js": "^9.5.0", + "@eslint/json": "^0.8.0", "@ota-meshi/eslint-plugin": "^0.17.3", "@ota-meshi/site-kit-eslint-editor-vue": "^0.2.0", "@types/debug": "^4.1.5", @@ -90,7 +91,7 @@ "env-cmd": "^10.1.0", "esbuild": "^0.24.0", "esbuild-register": "^3.2.0", - "eslint": "^9.5.0", + "eslint": "^9.16.0", "eslint-config-prettier": "^9.0.0", "eslint-plugin-eslint-plugin": "^6.0.0", "eslint-plugin-eslint-rule-tester": "^0.6.0", diff --git a/src/rules/block-mapping-colon-indicator-newline.ts b/src/rules/block-mapping-colon-indicator-newline.ts index e58da665..c3d5b27e 100644 --- a/src/rules/block-mapping-colon-indicator-newline.ts +++ b/src/rules/block-mapping-colon-indicator-newline.ts @@ -30,7 +30,7 @@ export default createRule("block-mapping-colon-indicator-newline", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } const option: "never" | "always" = context.options[0] || "never"; diff --git a/src/rules/block-mapping-question-indicator-newline.ts b/src/rules/block-mapping-question-indicator-newline.ts index 1a9bcd8b..32653973 100644 --- a/src/rules/block-mapping-question-indicator-newline.ts +++ b/src/rules/block-mapping-question-indicator-newline.ts @@ -26,7 +26,7 @@ export default createRule("block-mapping-question-indicator-newline", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } const option: "never" | "always" = context.options[0] || "never"; diff --git a/src/rules/block-mapping.ts b/src/rules/block-mapping.ts index 5a9dff02..75fc4374 100644 --- a/src/rules/block-mapping.ts +++ b/src/rules/block-mapping.ts @@ -101,7 +101,7 @@ export default createRule("block-mapping", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } const options = parseOptions(context.options[0]); diff --git a/src/rules/block-sequence-hyphen-indicator-newline.ts b/src/rules/block-sequence-hyphen-indicator-newline.ts index 0617fabf..3dbb6a6d 100644 --- a/src/rules/block-sequence-hyphen-indicator-newline.ts +++ b/src/rules/block-sequence-hyphen-indicator-newline.ts @@ -33,7 +33,7 @@ export default createRule("block-sequence-hyphen-indicator-newline", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } const style: "never" | "always" = context.options[0] || "never"; diff --git a/src/rules/block-sequence.ts b/src/rules/block-sequence.ts index 7eb060fb..7ef93995 100644 --- a/src/rules/block-sequence.ts +++ b/src/rules/block-sequence.ts @@ -111,7 +111,7 @@ export default createRule("block-sequence", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } const options = parseOptions(context.options[0]); diff --git a/src/rules/file-extension.ts b/src/rules/file-extension.ts index 668beb24..c10b65c3 100644 --- a/src/rules/file-extension.ts +++ b/src/rules/file-extension.ts @@ -31,7 +31,7 @@ export default createRule("file-extension", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } const expected: string = context.options[0]?.extension || "yaml"; diff --git a/src/rules/flow-mapping-curly-newline.ts b/src/rules/flow-mapping-curly-newline.ts index 6cd9f3e7..5ee72982 100644 --- a/src/rules/flow-mapping-curly-newline.ts +++ b/src/rules/flow-mapping-curly-newline.ts @@ -128,7 +128,7 @@ export default createRule("flow-mapping-curly-newline", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } const options = normalizeOptionValue(context.options[0]); diff --git a/src/rules/flow-mapping-curly-spacing.ts b/src/rules/flow-mapping-curly-spacing.ts index a6fde026..6f41ca36 100644 --- a/src/rules/flow-mapping-curly-spacing.ts +++ b/src/rules/flow-mapping-curly-spacing.ts @@ -51,7 +51,7 @@ export default createRule("flow-mapping-curly-spacing", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } diff --git a/src/rules/flow-sequence-bracket-newline.ts b/src/rules/flow-sequence-bracket-newline.ts index 208e357a..29d59df7 100644 --- a/src/rules/flow-sequence-bracket-newline.ts +++ b/src/rules/flow-sequence-bracket-newline.ts @@ -61,7 +61,7 @@ export default createRule("flow-sequence-bracket-newline", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } diff --git a/src/rules/flow-sequence-bracket-spacing.ts b/src/rules/flow-sequence-bracket-spacing.ts index b621d411..c5a29bd0 100644 --- a/src/rules/flow-sequence-bracket-spacing.ts +++ b/src/rules/flow-sequence-bracket-spacing.ts @@ -49,7 +49,7 @@ export default createRule("flow-sequence-bracket-spacing", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } diff --git a/src/rules/indent.ts b/src/rules/indent.ts index 988f2ca5..b6612cbd 100644 --- a/src/rules/indent.ts +++ b/src/rules/indent.ts @@ -116,7 +116,7 @@ export default createRule("indent", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } diff --git a/src/rules/key-name-casing.ts b/src/rules/key-name-casing.ts index 747f4480..3ab710d9 100644 --- a/src/rules/key-name-casing.ts +++ b/src/rules/key-name-casing.ts @@ -64,7 +64,7 @@ export default createRule("key-name-casing", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } const option: Option = { ...context.options[0] }; diff --git a/src/rules/key-spacing.ts b/src/rules/key-spacing.ts index 3dbfdd5d..0144d519 100644 --- a/src/rules/key-spacing.ts +++ b/src/rules/key-spacing.ts @@ -271,7 +271,7 @@ export default createRule("key-spacing", { */ function create(context: RuleContext): RuleListener { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } /** diff --git a/src/rules/no-empty-document.ts b/src/rules/no-empty-document.ts index 7d354bdd..0321da6e 100644 --- a/src/rules/no-empty-document.ts +++ b/src/rules/no-empty-document.ts @@ -18,7 +18,7 @@ export default createRule("no-empty-document", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } diff --git a/src/rules/no-empty-key.ts b/src/rules/no-empty-key.ts index 195a26fa..af99d77b 100644 --- a/src/rules/no-empty-key.ts +++ b/src/rules/no-empty-key.ts @@ -18,7 +18,7 @@ export default createRule("no-empty-key", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } diff --git a/src/rules/no-empty-mapping-value.ts b/src/rules/no-empty-mapping-value.ts index 4f75a873..dd4fa43d 100644 --- a/src/rules/no-empty-mapping-value.ts +++ b/src/rules/no-empty-mapping-value.ts @@ -18,7 +18,7 @@ export default createRule("no-empty-mapping-value", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } diff --git a/src/rules/no-empty-sequence-entry.ts b/src/rules/no-empty-sequence-entry.ts index ff2dd084..904ae487 100644 --- a/src/rules/no-empty-sequence-entry.ts +++ b/src/rules/no-empty-sequence-entry.ts @@ -19,7 +19,7 @@ export default createRule("no-empty-sequence-entry", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } diff --git a/src/rules/no-irregular-whitespace.ts b/src/rules/no-irregular-whitespace.ts index 018dab16..8bac11c1 100644 --- a/src/rules/no-irregular-whitespace.ts +++ b/src/rules/no-irregular-whitespace.ts @@ -44,7 +44,7 @@ export default createRule("no-irregular-whitespace", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } // Module store of error indexes that we have found diff --git a/src/rules/no-multiple-empty-lines.ts b/src/rules/no-multiple-empty-lines.ts index 252d612d..b195df0c 100644 --- a/src/rules/no-multiple-empty-lines.ts +++ b/src/rules/no-multiple-empty-lines.ts @@ -45,7 +45,7 @@ export default createRule("no-multiple-empty-lines", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } diff --git a/src/rules/no-tab-indent.ts b/src/rules/no-tab-indent.ts index 52c6d99d..e24f2b99 100644 --- a/src/rules/no-tab-indent.ts +++ b/src/rules/no-tab-indent.ts @@ -18,7 +18,7 @@ export default createRule("no-tab-indent", { }, create(context: RuleContext) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } return { diff --git a/src/rules/no-trailing-zeros.ts b/src/rules/no-trailing-zeros.ts index 6ac88636..efcab806 100644 --- a/src/rules/no-trailing-zeros.ts +++ b/src/rules/no-trailing-zeros.ts @@ -19,7 +19,7 @@ export default createRule("no-trailing-zeros", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } diff --git a/src/rules/plain-scalar.ts b/src/rules/plain-scalar.ts index 5282c513..630fd781 100644 --- a/src/rules/plain-scalar.ts +++ b/src/rules/plain-scalar.ts @@ -87,7 +87,7 @@ export default createRule("plain-scalar", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } type Option = { diff --git a/src/rules/quotes.ts b/src/rules/quotes.ts index 27366bbb..494705fd 100644 --- a/src/rules/quotes.ts +++ b/src/rules/quotes.ts @@ -31,7 +31,7 @@ export default createRule("quotes", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } const objectOption = context.options[0] || {}; diff --git a/src/rules/require-string-key.ts b/src/rules/require-string-key.ts index 6baca77c..50b10dbe 100644 --- a/src/rules/require-string-key.ts +++ b/src/rules/require-string-key.ts @@ -18,7 +18,7 @@ export default createRule("require-string-key", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } diff --git a/src/rules/sort-keys.ts b/src/rules/sort-keys.ts index a54c5c37..69c3443d 100644 --- a/src/rules/sort-keys.ts +++ b/src/rules/sort-keys.ts @@ -460,7 +460,7 @@ export default createRule("sort-keys", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } diff --git a/src/rules/sort-sequence-values.ts b/src/rules/sort-sequence-values.ts index 86da33fa..38cb5e0b 100644 --- a/src/rules/sort-sequence-values.ts +++ b/src/rules/sort-sequence-values.ts @@ -440,7 +440,7 @@ export default createRule("sort-sequence-values", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } // Parse options. diff --git a/src/rules/spaced-comment.ts b/src/rules/spaced-comment.ts index b1cd7719..a32370f4 100644 --- a/src/rules/spaced-comment.ts +++ b/src/rules/spaced-comment.ts @@ -159,7 +159,7 @@ export default createRule("spaced-comment", { }, create(context) { const sourceCode = getSourceCode(context); - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {}; } diff --git a/src/types.ts b/src/types.ts index f127e9e3..c075010f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -103,7 +103,7 @@ export interface SourceCode { ast: AST.YAMLProgram; lines: string[]; hasBOM: boolean; - parserServices: { + parserServices?: { isYAML?: true; parseError?: any; }; diff --git a/src/utils/index.ts b/src/utils/index.ts index 12530cd9..bdcc9b83 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -27,7 +27,7 @@ export function createRule( create(context: Rule.RuleContext): any { const sourceCode = getSourceCode(context); if ( - typeof sourceCode.parserServices.defineCustomBlocksVisitor === + typeof sourceCode.parserServices?.defineCustomBlocksVisitor === "function" && path.extname(getFilename(context)) === ".vue" ) { diff --git a/tests/fixtures/integrations/eslint-plugin/with-json/eslint.config.mjs b/tests/fixtures/integrations/eslint-plugin/with-json/eslint.config.mjs new file mode 100644 index 00000000..d6c886d5 --- /dev/null +++ b/tests/fixtures/integrations/eslint-plugin/with-json/eslint.config.mjs @@ -0,0 +1,38 @@ +import json from "@eslint/json"; +import { getPlugin } from "../plugin-store.cjs"; +const yaml = getPlugin() +export default [ + ...yaml.configs["flat/recommended"], + { + plugins: { + json, + }, + }, + + // lint JSON files + { + files: ["**/*.json"], + language: "json/json", + rules: { + "json/no-duplicate-keys": "error", + }, + }, + + // lint JSONC files + { + files: ["**/*.jsonc", ".vscode/*.json"], + language: "json/jsonc", + rules: { + "json/no-duplicate-keys": "error", + }, + }, + + // lint JSON5 files + { + files: ["**/*.json5"], + language: "json/json5", + rules: { + "json/no-duplicate-keys": "error", + }, + }, +] diff --git a/tests/fixtures/integrations/eslint-plugin/with-json/src/test.json b/tests/fixtures/integrations/eslint-plugin/with-json/src/test.json new file mode 100644 index 00000000..18d7acf5 --- /dev/null +++ b/tests/fixtures/integrations/eslint-plugin/with-json/src/test.json @@ -0,0 +1 @@ +{"foo": "bar"} \ No newline at end of file diff --git a/tests/fixtures/integrations/eslint-plugin/with-json/src/test.yml b/tests/fixtures/integrations/eslint-plugin/with-json/src/test.yml new file mode 100644 index 00000000..405a8a84 --- /dev/null +++ b/tests/fixtures/integrations/eslint-plugin/with-json/src/test.yml @@ -0,0 +1 @@ +"foo": "bar" \ No newline at end of file diff --git a/tests/src/eslint-plugin.ts b/tests/src/eslint-plugin.ts index e61df4d7..a714fdfc 100644 --- a/tests/src/eslint-plugin.ts +++ b/tests/src/eslint-plugin.ts @@ -60,17 +60,17 @@ describe("Integration with eslint-plugin-yml", () => { errors: 0, }, }, - // ...(semver.satisfies(process.version, ">=18") - // ? [ - // { - // dir: "with-json", - // expects: { - // files: 2, - // errors: 0, - // }, - // }, - // ] - // : []), + ...(semver.satisfies(process.version, ">=18") + ? [ + { + dir: "with-json", + expects: { + files: 2, + errors: 0, + }, + }, + ] + : []), ]) { it(dir, async () => { const engine = new ESLint({ diff --git a/tools/new-rule.ts b/tools/new-rule.ts index b0febf79..7384f46e 100644 --- a/tools/new-rule.ts +++ b/tools/new-rule.ts @@ -55,7 +55,7 @@ export default createRule("${ruleId}", { }, create(context) { const sourceCode = getSourceCode(context) - if (!sourceCode.parserServices.isYAML) { + if (!sourceCode.parserServices?.isYAML) { return {} } From ab56e6485175b451d8c021efc0d1e42522513112 Mon Sep 17 00:00:00 2001 From: Yosuke Ota Date: Sat, 30 Nov 2024 20:38:24 +0900 Subject: [PATCH 2/3] Create yellow-suits-nail.md --- .changeset/yellow-suits-nail.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/yellow-suits-nail.md diff --git a/.changeset/yellow-suits-nail.md b/.changeset/yellow-suits-nail.md new file mode 100644 index 00000000..24f26aac --- /dev/null +++ b/.changeset/yellow-suits-nail.md @@ -0,0 +1,5 @@ +--- +"eslint-plugin-yml": minor +--- + +feat: changed to prevent crash when used with language plugins From 12431d98ba043d40043f422cc209489255615ee0 Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Sat, 30 Nov 2024 20:41:10 +0900 Subject: [PATCH 3/3] fix --- tests/src/eslint-plugin.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/src/eslint-plugin.ts b/tests/src/eslint-plugin.ts index a714fdfc..b4a5755b 100644 --- a/tests/src/eslint-plugin.ts +++ b/tests/src/eslint-plugin.ts @@ -38,6 +38,7 @@ describe("Integration with eslint-plugin-yml", () => { it(dir, async () => { const engine = new LegacyESLint({ cwd: path.join(TEST_ROOT, dir), + // @ts-expect-error -- ignore extensions: [".js", ".yml"], plugins: { "eslint-plugin-yml": plugin as any }, }); @@ -60,7 +61,8 @@ describe("Integration with eslint-plugin-yml", () => { errors: 0, }, }, - ...(semver.satisfies(process.version, ">=18") + ...(semver.satisfies(process.version, ">=18") && + semver.satisfies(ESLint.version, ">=9") ? [ { dir: "with-json",