From 9b1b61dfe2c0251b4acc519928d5a4288a6798ee Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Sun, 29 Nov 2020 15:05:07 +0100 Subject: [PATCH 01/11] Require ESLint 7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 45390b8..c14d2a1 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,6 @@ "typescript": "4.1.2" }, "peerDependencies": { - "eslint": ">=3.14.1" + "eslint": ">=7.0.0" } } From 827706eeb42de05b90327f4ca65a1b16b38837f1 Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Sun, 29 Nov 2020 15:10:51 +0100 Subject: [PATCH 02/11] Use object spread instead of Object.assign --- index.js | 180 ++++++++++++++++++++++----------------------- react.js | 38 +++++----- test/rules.test.js | 2 +- 3 files changed, 108 insertions(+), 112 deletions(-) diff --git a/index.js b/index.js index 1cbfd47..2cc9d48 100644 --- a/index.js +++ b/index.js @@ -3,101 +3,99 @@ const includeDeprecated = !process.env.ESLINT_CONFIG_PRETTIER_NO_DEPRECATED; module.exports = { - rules: Object.assign( - { - // The following rules can be used in some cases. See the README for more - // information. (These are marked with `0` instead of `"off"` so that a - // script can distinguish them.) - "arrow-body-style": 0, - curly: 0, - "lines-around-comment": 0, - "max-len": 0, - "no-confusing-arrow": 0, - "no-mixed-operators": 0, - "no-tabs": 0, - "no-unexpected-multiline": 0, - "prefer-arrow-callback": 0, - quotes: 0, - // The rest are rules that you never need to enable when using Prettier. - "array-bracket-newline": "off", - "array-bracket-spacing": "off", - "array-element-newline": "off", - "arrow-parens": "off", - "arrow-spacing": "off", - "block-spacing": "off", - "brace-style": "off", - "comma-dangle": "off", - "comma-spacing": "off", - "comma-style": "off", - "computed-property-spacing": "off", - "dot-location": "off", - "eol-last": "off", - "func-call-spacing": "off", - "function-call-argument-newline": "off", - "function-paren-newline": "off", - "generator-star": "off", - "generator-star-spacing": "off", - "implicit-arrow-linebreak": "off", - indent: "off", - "jsx-quotes": "off", - "key-spacing": "off", - "keyword-spacing": "off", - "linebreak-style": "off", - "multiline-ternary": "off", - "newline-per-chained-call": "off", - "new-parens": "off", - "no-arrow-condition": "off", - "no-comma-dangle": "off", - "no-extra-parens": "off", - "no-extra-semi": "off", - "no-floating-decimal": "off", - "no-mixed-spaces-and-tabs": "off", - "no-multi-spaces": "off", - "no-multiple-empty-lines": "off", - "no-reserved-keys": "off", - "no-space-before-semi": "off", - "no-trailing-spaces": "off", - "no-whitespace-before-property": "off", - "no-wrap-func": "off", - "nonblock-statement-body-position": "off", - "object-curly-newline": "off", - "object-curly-spacing": "off", - "object-property-newline": "off", - "one-var-declaration-per-line": "off", - "operator-linebreak": "off", - "padded-blocks": "off", - "quote-props": "off", - "rest-spread-spacing": "off", - semi: "off", - "semi-spacing": "off", - "semi-style": "off", - "space-after-function-name": "off", - "space-after-keywords": "off", - "space-before-blocks": "off", - "space-before-function-paren": "off", - "space-before-function-parentheses": "off", - "space-before-keywords": "off", - "space-in-brackets": "off", - "space-in-parens": "off", - "space-infix-ops": "off", - "space-return-throw-case": "off", - "space-unary-ops": "off", - "space-unary-word-ops": "off", - "switch-colon-spacing": "off", - "template-curly-spacing": "off", - "template-tag-spacing": "off", - "unicode-bom": "off", - "wrap-iife": "off", - "wrap-regex": "off", - "yield-star-spacing": "off", - }, - includeDeprecated && { + rules: { + // The following rules can be used in some cases. See the README for more + // information. (These are marked with `0` instead of `"off"` so that a + // script can distinguish them.) + "arrow-body-style": 0, + curly: 0, + "lines-around-comment": 0, + "max-len": 0, + "no-confusing-arrow": 0, + "no-mixed-operators": 0, + "no-tabs": 0, + "no-unexpected-multiline": 0, + "prefer-arrow-callback": 0, + quotes: 0, + // The rest are rules that you never need to enable when using Prettier. + "array-bracket-newline": "off", + "array-bracket-spacing": "off", + "array-element-newline": "off", + "arrow-parens": "off", + "arrow-spacing": "off", + "block-spacing": "off", + "brace-style": "off", + "comma-dangle": "off", + "comma-spacing": "off", + "comma-style": "off", + "computed-property-spacing": "off", + "dot-location": "off", + "eol-last": "off", + "func-call-spacing": "off", + "function-call-argument-newline": "off", + "function-paren-newline": "off", + "generator-star": "off", + "generator-star-spacing": "off", + "implicit-arrow-linebreak": "off", + indent: "off", + "jsx-quotes": "off", + "key-spacing": "off", + "keyword-spacing": "off", + "linebreak-style": "off", + "multiline-ternary": "off", + "newline-per-chained-call": "off", + "new-parens": "off", + "no-arrow-condition": "off", + "no-comma-dangle": "off", + "no-extra-parens": "off", + "no-extra-semi": "off", + "no-floating-decimal": "off", + "no-mixed-spaces-and-tabs": "off", + "no-multi-spaces": "off", + "no-multiple-empty-lines": "off", + "no-reserved-keys": "off", + "no-space-before-semi": "off", + "no-trailing-spaces": "off", + "no-whitespace-before-property": "off", + "no-wrap-func": "off", + "nonblock-statement-body-position": "off", + "object-curly-newline": "off", + "object-curly-spacing": "off", + "object-property-newline": "off", + "one-var-declaration-per-line": "off", + "operator-linebreak": "off", + "padded-blocks": "off", + "quote-props": "off", + "rest-spread-spacing": "off", + semi: "off", + "semi-spacing": "off", + "semi-style": "off", + "space-after-function-name": "off", + "space-after-keywords": "off", + "space-before-blocks": "off", + "space-before-function-paren": "off", + "space-before-function-parentheses": "off", + "space-before-keywords": "off", + "space-in-brackets": "off", + "space-in-parens": "off", + "space-infix-ops": "off", + "space-return-throw-case": "off", + "space-unary-ops": "off", + "space-unary-word-ops": "off", + "switch-colon-spacing": "off", + "template-curly-spacing": "off", + "template-tag-spacing": "off", + "unicode-bom": "off", + "wrap-iife": "off", + "wrap-regex": "off", + "yield-star-spacing": "off", + ...(includeDeprecated && { // Deprecated since version 4.0.0. // https://github.com/eslint/eslint/pull/8286 "indent-legacy": "off", // Deprecated since version 3.3.0. // https://eslint.org/docs/rules/no-spaced-func "no-spaced-func": "off", - } - ), + }), + }, }; diff --git a/react.js b/react.js index 3f48553..5d79ba9 100644 --- a/react.js +++ b/react.js @@ -3,27 +3,25 @@ const includeDeprecated = !process.env.ESLINT_CONFIG_PRETTIER_NO_DEPRECATED; module.exports = { - rules: Object.assign( - { - "react/jsx-child-element-spacing": "off", - "react/jsx-closing-bracket-location": "off", - "react/jsx-closing-tag-location": "off", - "react/jsx-curly-newline": "off", - "react/jsx-curly-spacing": "off", - "react/jsx-equals-spacing": "off", - "react/jsx-first-prop-new-line": "off", - "react/jsx-indent": "off", - "react/jsx-indent-props": "off", - "react/jsx-max-props-per-line": "off", - "react/jsx-one-expression-per-line": "off", - "react/jsx-props-no-multi-spaces": "off", - "react/jsx-tag-spacing": "off", - "react/jsx-wrap-multilines": "off", - }, - includeDeprecated && { + rules: { + "react/jsx-child-element-spacing": "off", + "react/jsx-closing-bracket-location": "off", + "react/jsx-closing-tag-location": "off", + "react/jsx-curly-newline": "off", + "react/jsx-curly-spacing": "off", + "react/jsx-equals-spacing": "off", + "react/jsx-first-prop-new-line": "off", + "react/jsx-indent": "off", + "react/jsx-indent-props": "off", + "react/jsx-max-props-per-line": "off", + "react/jsx-one-expression-per-line": "off", + "react/jsx-props-no-multi-spaces": "off", + "react/jsx-tag-spacing": "off", + "react/jsx-wrap-multilines": "off", + ...(includeDeprecated && { // Deprecated since version 7.0.0. // https://github.com/yannickcr/eslint-plugin-react/blob/master/CHANGELOG.md#700---2017-05-06 "react/jsx-space-before-closing": "off", - } - ), + }), + }, }; diff --git a/test/rules.test.js b/test/rules.test.js index 329a8e0..13f2856 100644 --- a/test/rules.test.js +++ b/test/rules.test.js @@ -37,7 +37,7 @@ function createTestConfigDir() { return obj; }, {}); - const newConfig = Object.assign({}, config, { rules: newRules }); + const newConfig = { ...config, rules: newRules }; fs.writeFileSync( path.join(TEST_CONFIG_DIR, ruleFileName), From 4ab6937398f42fa3832f476589513e94b8be4ad1 Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Sun, 29 Nov 2020 17:21:54 +0100 Subject: [PATCH 03/11] Use ESLint API instead of --print-config and stdin --- README.md | 23 +++++++--- bin/cli.js | 109 ++++++++++++++++++++------------------------- package-lock.json | 5 --- package.json | 12 ++--- test/cli.test.js | 100 +++++++---------------------------------- test/rules.test.js | 4 +- 6 files changed, 88 insertions(+), 165 deletions(-) diff --git a/README.md b/README.md index 348c775..72863e6 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Note that this config _only_ turns rules _off,_ so it only makes sense using it - [Installation](#installation) - [Excluding deprecated rules](#excluding-deprecated-rules) - [CLI helper tool](#cli-helper-tool) + - [Legacy](#legacy) - [Special rules](#special-rules) - [arrow-body-style and prefer-arrow-callback](#arrow-body-style-and-prefer-arrow-callback) - [curly](#curly) @@ -115,17 +116,15 @@ eslint-config-prettier also ships with a little CLI tool to help you check if yo You can run it using `npx`: ``` -npx eslint --print-config path/to/main.js | npx eslint-config-prettier-check +npx eslint-config-prettier path/to/main.js ``` (Change `path/to/main.js` to a file that exists in your project.) -In theory you need to run `npx eslint --print-config file.js | npx eslint-config-prettier-check` for every single file in your project to be 100% sure that there are no conflicting rules, because ESLint supports having different rules for different files. But usually you’ll have about the same rules for all files, so it is enough to run the command on one file (pick one that you won’t be moving). If you use [multiple configuration files] or [overrides], you can (but you probably don’t need to!) run the above script several times with different `--print-config` arguments, such as: +In theory you need to run the tool for every single file in your project to be 100% sure that there are no conflicting rules, because ESLint supports having different rules for different files. But usually you’ll have about the same rules for all files, so it is good enough to run the command on one file. But if you use [multiple configuration files] or [overrides], you can provide several files check: ``` -npx eslint --print-config index.js | npx eslint-config-prettier-check -npx eslint --print-config test/index.js | npx eslint-config-prettier-check -npx eslint --print-config legacy/main.js | npx eslint-config-prettier-check +npx eslint-config-prettier index.js test/index.js legacy/main.js ``` Exit codes: @@ -134,6 +133,20 @@ Exit codes: - 1: Unexpected error. - 2: Conflicting rules found. +### Legacy + +eslint-config-prettier versions before 7.0.0 had a slightly different CLI tool that was run in a different way. For example: + +``` +npx eslint --print-config index.js | npx eslint-config-prettier-check +``` + +If you find something like that in a tutorial, this is what the command looks like in 7.0.0 or later: + +``` +npx eslint-config-prettier index.js +``` + ## Special rules There a few rules that eslint-config-prettier disables that actually can be enabled in some cases. diff --git a/bin/cli.js b/bin/cli.js index 208b143..aa6c617 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -4,38 +4,28 @@ const fs = require("fs"); const path = require("path"); -const getStdin = require("get-stdin"); +const { ESLint } = require("eslint"); const validators = require("./validators"); const SPECIAL_RULES_URL = "https://github.com/prettier/eslint-config-prettier#special-rules"; if (module === require.main) { - if (process.argv.length > 2 || process.stdin.isTTY) { - console.error( - [ - "This tool checks whether an ESLint configuration contains rules that are", - "unnecessary or conflict with Prettier. It’s supposed to be run like this:", - "", - " npx eslint --print-config path/to/main.js | npx eslint-config-prettier-check", - " npx eslint --print-config test/index.js | npx eslint-config-prettier-check", - "", - "Exit codes:", - "", - "0: No automatically detectable problems found.", - "1: Unexpected error.", - "2: Conflicting rules found.", - "", - "For more information, see:", - "https://github.com/prettier/eslint-config-prettier#cli-helper-tool", - ].join("\n") - ); + const args = process.argv.slice(2); + + if (args.length === 0) { + console.error(help()); process.exit(1); } - getStdin() - .then((string) => { - const result = processString(string); + const eslint = new ESLint(); + + Promise.all(args.map((file) => eslint.calculateConfigForFile(file))) + .then((configs) => { + const rules = [].concat( + ...configs.map((config) => Object.entries(config.rules)) + ); + const result = processRules(rules); if (result.stderr) { console.error(result.stderr); } @@ -45,34 +35,32 @@ if (module === require.main) { process.exit(result.code); }) .catch((error) => { - console.error("Unexpected error", error); + console.error(error.message); process.exit(1); }); } -function processString(string) { - let config; - try { - config = JSON.parse(string); - } catch (error) { - return { - stderr: `Failed to parse JSON:\n${error.message}`, - code: 1, - }; - } +function help() { + return ` +Usage: npx eslint-config-prettier FILE... - if ( - !( - Object.prototype.toString.call(config) === "[object Object]" && - Object.prototype.toString.call(config.rules) === "[object Object]" - ) - ) { - return { - stderr: `Expected a \`{"rules: {...}"}\` JSON object, but got:\n${string}`, - code: 1, - }; - } +Resolves an ESLint configuration for every given FILE and checks if they +contain rules that are unnecessary or conflict with Prettier. Example: + + npx eslint-config-prettier index.js test/index.js other/file/to/check.js + +Exit codes: + +0: No automatically detectable problems found. +1: General error. +2: Conflicting rules found. +For more information, see: +https://github.com/prettier/eslint-config-prettier#cli-helper-tool + `.trim(); +} + +function processRules(configRules) { // This used to look at "files" in package.json, but that is not reliable due // to an npm bug. See: // https://github.com/prettier/eslint-config-prettier/issues/57 @@ -84,10 +72,7 @@ function processString(string) { .map((ruleFileName) => require(`../${ruleFileName}`).rules) ); - const regularRules = filterRules( - allRules, - (ruleName, value) => value === "off" - ); + const regularRules = filterRules(allRules, (_, value) => value === "off"); const optionsRules = filterRules( allRules, (ruleName, value) => value === 0 && ruleName in validators @@ -97,12 +82,10 @@ function processString(string) { (ruleName, value) => value === 0 && !(ruleName in validators) ); - const flaggedRules = Object.keys(config.rules) - .map((ruleName) => { - const value = config.rules[ruleName]; + const flaggedRules = configRules + .map(([ruleName, value]) => { const arrayValue = Array.isArray(value) ? value : [value]; - const level = arrayValue[0]; - const options = arrayValue.slice(1); + const [level, ...options] = arrayValue; const isOff = level === "off" || level === 0; return !isOff && ruleName in allRules ? { ruleName, options } : null; }) @@ -182,18 +165,22 @@ function processString(string) { } function filterRules(rules, fn) { - return Object.keys(rules) - .filter((ruleName) => fn(ruleName, rules[ruleName])) - .reduce((obj, ruleName) => { + return Object.entries(rules) + .filter(([ruleName, value]) => fn(ruleName, value)) + .reduce((obj, [ruleName]) => { obj[ruleName] = true; return obj; }, Object.create(null)); } function filterRuleNames(rules, fn) { - return rules - .filter((rule) => fn(rule.ruleName, rule.options)) - .map((rule) => rule.ruleName); + return [ + ...new Set( + rules + .filter((rule) => fn(rule.ruleName, rule.options)) + .map((rule) => rule.ruleName) + ), + ]; } function printRuleNames(ruleNames) { @@ -204,4 +191,4 @@ function printRuleNames(ruleNames) { .join("\n"); } -exports.processString = processString; +exports.processRules = processRules; diff --git a/package-lock.json b/package-lock.json index 6a60ed0..e747aed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3592,11 +3592,6 @@ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true }, - "get-stdin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==" - }, "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", diff --git a/package.json b/package.json index c14d2a1..874f470 100644 --- a/package.json +++ b/package.json @@ -16,9 +16,7 @@ "unicorn.js", "vue.js" ], - "bin": { - "eslint-config-prettier-check": "bin/cli.js" - }, + "bin": "bin/cli.js", "keywords": [ "eslint", "eslintconfig", @@ -32,13 +30,11 @@ "test:lint-rules": "eslint index.js --config test-config/.eslintrc.js --format json", "test:deprecated": "eslint-find-rules --deprecated index.js", "test:jest": "jest", - "test:cli-sanity": "eslint --print-config index.js | node ./bin/cli.js", - "test:cli-sanity-warning": "eslint --print-config ./bin/cli.js | node ./bin/cli.js", + "test:cli-sanity": "node ./bin/cli.js index.js", + "test:cli-sanity-warning": "node ./bin/cli.js react.js ./bin/cli.js", "test": "npm run test:lint && npm run test:jest && npm run test:cli-sanity && npm run test:cli-sanity-warning" }, - "dependencies": { - "get-stdin": "^6.0.0" - }, + "dependencies": {}, "devDependencies": { "@typescript-eslint/eslint-plugin": "4.8.2", "@typescript-eslint/parser": "4.8.2", diff --git a/test/cli.test.js b/test/cli.test.js index a5ba260..069cc45 100644 --- a/test/cli.test.js +++ b/test/cli.test.js @@ -7,16 +7,13 @@ const onPatterns = [1, 2, "warn", "error", [1], [2], ["warn"], ["error"]]; function createRules(rules, pattern) { const arrayPattern = Array.isArray(pattern) ? pattern : [pattern]; - const rulesString = rules - .map((rule) => { - const value = Array.isArray(rule) - ? arrayPattern.concat(rule.slice(1)) - : pattern; - const name = Array.isArray(rule) ? rule[0] : rule; - return `"${name}": ${JSON.stringify(value)}`; - }) - .join(", "); - return `{"rules": {${rulesString}}}`; + return rules.map((rule) => { + const value = Array.isArray(rule) + ? arrayPattern.concat(rule.slice(1)) + : pattern; + const name = Array.isArray(rule) ? rule[0] : rule; + return [name, value]; + }); } describe("does not flag", () => { @@ -24,7 +21,7 @@ describe("does not flag", () => { const results = offPatterns.map((pattern) => ({ pattern: JSON.stringify(pattern), - result: cli.processString(createRules(rules, pattern)), + result: cli.processRules(createRules(rules, pattern)), })); test("result", () => { @@ -49,7 +46,7 @@ describe("does flag", () => { const results = onPatterns.map( (pattern) => ({ pattern: JSON.stringify(pattern), - result: cli.processString(createRules(rules, pattern)), + result: cli.processRules(createRules(rules, pattern)), }), {} ); @@ -74,7 +71,7 @@ Object { test("no results", () => { const rules = ["strict", "curly"]; - expect(cli.processString(createRules(rules, "error"))).toMatchInlineSnapshot(` + expect(cli.processRules(createRules(rules, "error"))).toMatchInlineSnapshot(` Object { "code": 0, "stdout": "No rules that are unnecessary or conflict with Prettier were found.", @@ -84,7 +81,7 @@ Object { test("conflicting options", () => { const rules = ["strict", ["curly", "multi-line"]]; - expect(cli.processString(createRules(rules, "error"))).toMatchInlineSnapshot(` + expect(cli.processRules(createRules(rules, "error"))).toMatchInlineSnapshot(` Object { "code": 2, "stdout": "The following rules are enabled with options that might conflict with Prettier. See: @@ -97,7 +94,7 @@ https://github.com/prettier/eslint-config-prettier#special-rules test("special rules", () => { const rules = ["strict", "max-len"]; - expect(cli.processString(createRules(rules, "error"))).toMatchInlineSnapshot(` + expect(cli.processRules(createRules(rules, "error"))).toMatchInlineSnapshot(` Object { "code": 0, "stdout": "No rules that are unnecessary or conflict with Prettier were found. @@ -115,12 +112,16 @@ test("all the things", () => { "strict", "max-len", "arrow-spacing", + "arrow-spacing", "quotes", + ["quotes", "double"], "arrow-parens", "no-tabs", "lines-around-comment", "no-unexpected-multiline", "no-mixed-operators", + "curly", + ["curly", "multi-line"], ["curly", "multi-or-nest", "consistent"], ["no-confusing-arrow", { allowParens: true }], "react/jsx-indent", @@ -129,7 +130,7 @@ test("all the things", () => { "prefer-arrow-callback", "arrow-body-style", ]; - expect(cli.processString(createRules(rules, "error"))).toMatchInlineSnapshot(` + expect(cli.processRules(createRules(rules, "error"))).toMatchInlineSnapshot(` Object { "code": 2, "stdout": "The following rules are unnecessary or might conflict with Prettier: @@ -160,70 +161,3 @@ https://github.com/prettier/eslint-config-prettier#special-rules } `); }); - -test("invalid JSON", () => { - expect(cli.processString("a")).toMatchInlineSnapshot(` -Object { - "code": 1, - "stderr": "Failed to parse JSON: -Unexpected token a in JSON at position 0", -} -`); - expect(cli.processString('{"rules": {')).toMatchInlineSnapshot(` -Object { - "code": 1, - "stderr": "Failed to parse JSON: -Unexpected end of JSON input", -} -`); -}); - -test("invalid config", () => { - expect(cli.processString("null")).toMatchInlineSnapshot(` -Object { - "code": 1, - "stderr": "Expected a \`{\\"rules: {...}\\"}\` JSON object, but got: -null", -} -`); - - expect(cli.processString("true")).toMatchInlineSnapshot(` -Object { - "code": 1, - "stderr": "Expected a \`{\\"rules: {...}\\"}\` JSON object, but got: -true", -} -`); - - expect(cli.processString("false")).toMatchInlineSnapshot(` -Object { - "code": 1, - "stderr": "Expected a \`{\\"rules: {...}\\"}\` JSON object, but got: -false", -} -`); - - expect(cli.processString("1")).toMatchInlineSnapshot(` -Object { - "code": 1, - "stderr": "Expected a \`{\\"rules: {...}\\"}\` JSON object, but got: -1", -} -`); - - expect(cli.processString('"string"')).toMatchInlineSnapshot(` -Object { - "code": 1, - "stderr": "Expected a \`{\\"rules: {...}\\"}\` JSON object, but got: -\\"string\\"", -} -`); - - expect(cli.processString("[1, true]")).toMatchInlineSnapshot(` -Object { - "code": 1, - "stderr": "Expected a \`{\\"rules: {...}\\"}\` JSON object, but got: -[1, true]", -} -`); -}); diff --git a/test/rules.test.js b/test/rules.test.js index 13f2856..84e52ae 100644 --- a/test/rules.test.js +++ b/test/rules.test.js @@ -128,9 +128,7 @@ describe('all rules are set to "off" or 0', () => { ...ruleFiles.map((ruleFileName) => require(`../${ruleFileName}`).rules) ); - Object.keys(allRules).forEach((name) => { - const value = allRules[name]; - + Object.entries(allRules).forEach(([name, value]) => { test(name, () => { expect(value === "off" || value === 0).toBe(true); }); From 7867a9c0e3610f20075301334a99a4e55d3cec78 Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Sun, 29 Nov 2020 17:42:55 +0100 Subject: [PATCH 04/11] Turn no-tabs into a validatable rule Closes #55. --- README.md | 28 ++++------------------------ bin/validators.js | 9 +++++++++ test/cli.test.js | 2 +- test/validators.test.js | 5 +++++ 4 files changed, 19 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 72863e6..424c160 100644 --- a/README.md +++ b/README.md @@ -401,31 +401,13 @@ Example ESLint configuration: ### [no-tabs] -**This rule requires certain Prettier options.** - -This rule disallows the use of tab characters at all. It can be used just fine with Prettier as long as you don’t configure Prettier to indent using tabs. - -Example ESLint configuration: - - -```json -{ - "rules": { - "no-tabs": "error" - } -} -``` +**This rule requires certain options.** -Example Prettier configuration (this is the default, so adding this is not required): +This rule disallows the use of tab characters. By default the rule forbids _all_ tab characters. That can be used just fine with Prettier as long as you don’t configure Prettier to indent using tabs. - -```json -{ - "useTabs": false -} -``` +Luckily, it’s possible to configure the rule so that it works regardless of whether Prettier uses spaces or tabs: Set `allowIndentationTabs` to `true`. This way Prettier takes care of your indentation, while the `no-tabs` takes care of potential tab characters anywhere else in your code. -**Note:** Since [ESlint 5.7.0] this rule can be configured to work regardless of your Prettier configuration: +Example ESLint configuration: ```json @@ -436,8 +418,6 @@ Example Prettier configuration (this is the default, so adding this is not requi } ``` -A future version of eslint-config-prettier might check for that automatically. - ### [no-unexpected-multiline] **This rule requires special attention when writing code.** diff --git a/bin/validators.js b/bin/validators.js index a6a9b8a..5646e97 100644 --- a/bin/validators.js +++ b/bin/validators.js @@ -39,6 +39,15 @@ module.exports = { return firstOption ? firstOption.allowParens === false : false; }, + "no-tabs"(options) { + if (options.length === 0) { + return false; + } + + const firstOption = options[0]; + return Boolean(firstOption && firstOption.allowIndentationTabs); + }, + "vue/html-self-closing"(options) { if (options.length === 0) { return false; diff --git a/test/cli.test.js b/test/cli.test.js index 069cc45..a907c82 100644 --- a/test/cli.test.js +++ b/test/cli.test.js @@ -146,6 +146,7 @@ https://github.com/prettier/eslint-config-prettier#special-rules - curly - lines-around-comment - no-confusing-arrow +- no-tabs - vue/html-self-closing The following rules are enabled but cannot be automatically checked. See: @@ -154,7 +155,6 @@ https://github.com/prettier/eslint-config-prettier#special-rules - arrow-body-style - max-len - no-mixed-operators -- no-tabs - no-unexpected-multiline - prefer-arrow-callback - quotes", diff --git a/test/validators.test.js b/test/validators.test.js index 9f96e8d..52cb24f 100644 --- a/test/validators.test.js +++ b/test/validators.test.js @@ -60,6 +60,11 @@ rule("no-confusing-arrow", { invalid: [[], [null], [{ allowParens: true }], [{ other: true }]], }); +rule("no-tabs", { + valid: [[{ allowIndentationTabs: true }]], + invalid: [[], [null], [{ allowIndentationTabs: false }], [{ other: true }]], +}); + rule("vue/html-self-closing", { valid: [ [{ html: { void: "any" } }], From 8a4cdcfbba2e1ff15c4fefcdbabd7a07c701d37f Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Sun, 29 Nov 2020 17:59:52 +0100 Subject: [PATCH 05/11] Move eslint-plugin-prettier to its own file like all other plugins Closes #155. --- .eslintrc.base.js | 4 +- README.md | 68 +++++++++++++-- bin/cli.js | 17 ++-- bin/validators.js | 11 +++ index.js | 2 - package.json | 1 + prettier.js | 10 +++ test-lint/prettier.js | 14 +++ test/cli.test.js | 156 ++++++++++++++++++++-------------- test/lint-verify-fail.test.js | 5 +- 10 files changed, 211 insertions(+), 77 deletions(-) create mode 100644 prettier.js create mode 100644 test-lint/prettier.js diff --git a/.eslintrc.base.js b/.eslintrc.base.js index 3e43b40..e3697df 100644 --- a/.eslintrc.base.js +++ b/.eslintrc.base.js @@ -37,7 +37,9 @@ module.exports = { strict: "error", "prefer-spread": "off", "require-jsdoc": "off", - "prettier/prettier": ["error", {}], + "prettier/prettier": "error", + // Force a conflict with eslint-plugin-prettier in test-lint/prettier.js. + "prefer-arrow-callback": "error", // Force a conflict with Prettier in test-lint/flowtype.js. "flowtype/object-type-delimiter": ["error", "semicolon"], "react/jsx-filename-extension": "off", diff --git a/README.md b/README.md index 424c160..258a73c 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ Note that this config _only_ turns rules _off,_ so it only makes sense using it - [Installation](#installation) + - [eslint-plugin-prettier](#eslint-plugin-prettier) - [Excluding deprecated rules](#excluding-deprecated-rules) - [CLI helper tool](#cli-helper-tool) - [Legacy](#legacy) @@ -62,6 +63,7 @@ A few ESLint plugins are supported as well: - [@typescript-eslint/eslint-plugin] - [eslint-plugin-babel] - [eslint-plugin-flowtype] +- [eslint-plugin-prettier] - [eslint-plugin-react] - [eslint-plugin-standard] - [eslint-plugin-unicorn] @@ -78,6 +80,7 @@ Add extra exclusions for the plugins you use like so: "prettier/@typescript-eslint", "prettier/babel", "prettier/flowtype", + "prettier/prettier", "prettier/react", "prettier/standard", "prettier/unicorn", @@ -101,6 +104,54 @@ If you extend a config which uses a plugin, it is recommended to add `"prettier/ If you’re unsure which plugins are used, you can usually find them in your `package.json`. +### eslint-plugin-prettier + +In the above section you might have noticed this plugin being mentioned: + +[eslint-plugin-prettier][eslint-plugin-prettier] + +Just to clear any confusion, the repo you’re currently looking at is: + +eslint-config-prettier + +So what’s the difference? + +- eslint-plugin-prettier adds a new _rule_ that lets you run Prettier from within ESLint as if it was a regular old ESLint rule. +- eslint-config-prettier just turns off a bunch of rules (that are unnecessary or conflict with Prettier). + +To make things even more confusing, eslint-plugin-prettier _also_ provides a _config_ you can extend. It’s called `"plugin:prettier/recommended"`. All that config does is: + +```json +{ + "extends": ["prettier", "prettier/prettier"], + "plugins": ["prettier"], + "rules": { + "prettier/prettier": "error" + } +} +``` + +Ugh, that’s a lot of `prettier` and `prettier/prettier`! What is all of that doing? Let’s start from the bottom: + +- `"rules": { "prettier/prettier": "error" }` turns on the _rule_ that eslint-plugin-prettier provides, that lets you run Prettier from within ESLint. + +- `"plugins": ["prettier"]` registers eslint-plugin-prettier as a plugin, so ESLint knows what `"prettier/prettier": "error"` is. + +- `"extends"` is the interesting part. This requires you to also install eslint-config-prettier (this repo), because the listed configs comes from _this_ repo, not from the plugin’s repo! + + - `"prettier"` is the base config which disables ESLint core rules. + - `"prettier/prettier"` is specific config for eslint-plugin-prettier which disables [two ESLint core rules][eslint-plugin-prettier-special] that conflict only with eslint-plugin-prettier (not Prettier itself). + +Note that even if you use `"plugin:prettier/recommended"`, you might still need to add more stuff to the `"extends"` array, depending on which other plugins you use. For example: + +```json +{ + "extends": ["plugin:prettier/recommended", "prettier/@typescript-eslint"] +} +``` + +**Note:** [eslint-plugin-prettier has some downsides][eslint-plugin-prettier-downsides] that you might want to read about. + ### Excluding deprecated rules Some of the rules that eslint-config-prettier turns off may be deprecated. **This is perfectly fine,** but if you really need to omit the deprecated rules, you can do so by setting the `ESLINT_CONFIG_PRETTIER_NO_DEPRECATED` environment variable to a non-empty value. For example: @@ -155,7 +206,7 @@ There a few rules that eslint-config-prettier disables that actually can be enab - Some require special attention when writing code. The CLI helper tool warns you if any of those rules are enabled, but can’t tell if anything is problematic. - Some can cause problems if using [eslint-plugin-prettier] and `--fix`. -For maximum ease of use, the special rules are disabled by default. If you want them, you need to explicitly specify them in your ESLint config. +For maximum ease of use, the special rules are disabled by default (provided that you include all needed things in `"extends"`). If you want them, you need to explicitly specify them in your ESLint config. ### [arrow-body-style] and [prefer-arrow-callback] @@ -180,6 +231,10 @@ See these issues for more information: When the autofix bug in ESLint has been fixed, the special case for these rules can be removed. +Note: You need to put `"prettier/prettier"` in your `"extends"` array if you want these rules to be turned off. (Yes, there’s both a _rule_ called `"prettier/prettier"` and a _config_ called `"prettier/prettier"`.) + +Note: The CLI tool only reports these as problematic if the `"prettier/prettier"` _rule_ is enabled for the same file. + ### [curly] **This rule requires certain options.** @@ -692,6 +747,7 @@ eslint-config-prettier has been tested with: - @typescript-eslint/eslint-plugin 4.8.2 - eslint-plugin-babel 5.3.1 - eslint-plugin-flowtype 5.2.0 +- eslint-plugin-prettier 3.1.4 - eslint-plugin-react 7.21.5 - eslint-plugin-standard 4.0.2 - eslint-plugin-unicorn 23.0.0 @@ -733,7 +789,7 @@ Finally, you need to mention the plugin in several places: - Add `"foobar.js"` to the "files" field in `package.json`. - Add eslint-plugin-foobar to the "devDependencies" field in `package.json`. - Make sure that at least one rule from eslint-plugin-foobar gets used in `.eslintrc.base.js`. -- Add it to the list of supported plugins, to the example config and to Contributing section in `README.md`. +- Add it to the list of supported plugins and to the Contributing section in `README.md`. When you’re done, run `npm test` to verify that you got it all right. It runs several other npm scripts: @@ -752,18 +808,19 @@ When you’re done, run `npm test` to verify that you got it all right. It runs [@typescript-eslint/eslint-plugin]: https://github.com/typescript-eslint/typescript-eslint [@typescript-eslint/quotes]: https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/quotes.md -[eslint 5.7.0]: https://eslint.org/blog/2018/10/eslint-v5.7.0-released -[prettier]: https://github.com/prettier/prettier [arrow-body-style]: https://eslint.org/docs/rules/arrow-body-style [babel/quotes]: https://github.com/babel/eslint-plugin-babel#rules [curly]: https://eslint.org/docs/rules/curly +[eslint 5.7.0]: https://eslint.org/blog/2018/10/eslint-v5.7.0-released [eslint-config-airbnb]: https://www.npmjs.com/package/eslint-config-airbnb [eslint-config-prettier#31]: https://github.com/prettier/eslint-config-prettier/issues/31 [eslint-config-prettier#71]: https://github.com/prettier/eslint-config-prettier/issues/71 [eslint-plugin-babel]: https://github.com/babel/eslint-plugin-babel [eslint-plugin-flowtype]: https://github.com/gajus/eslint-plugin-flowtype -[eslint-plugin-prettier#65]: https://github.com/prettier/eslint-plugin-prettier/issues/65 +[eslint-plugin-prettier-downsides]: https://prettier.io/docs/en/integrating-with-linters.html#notes +[eslint-plugin-prettier-special]: #arrow-body-style-and-prefer-arrow-callback [eslint-plugin-prettier]: https://github.com/prettier/eslint-plugin-prettier +[eslint-plugin-prettier#65]: https://github.com/prettier/eslint-plugin-prettier/issues/65 [eslint-plugin-react]: https://github.com/yannickcr/eslint-plugin-react [eslint-plugin-standard]: https://github.com/xjamundx/eslint-plugin-standard [eslint-plugin-unicorn]: https://github.com/sindresorhus/eslint-plugin-unicorn @@ -780,6 +837,7 @@ When you’re done, run `npm test` to verify that you got it all right. It runs [no-unexpected-multiline]: https://eslint.org/docs/rules/no-unexpected-multiline [overrides]: https://eslint.org/docs/user-guide/configuring#configuration-based-on-glob-patterns [prefer-arrow-callback]: https://eslint.org/docs/rules/prefer-arrow-callback +[prettier]: https://github.com/prettier/prettier [quotes]: https://eslint.org/docs/rules/quotes [singlequote]: https://prettier.io/docs/en/options.html#quotes [string formatting rules]: https://prettier.io/docs/en/rationale.html#strings diff --git a/bin/cli.js b/bin/cli.js index aa6c617..f649336 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -23,7 +23,9 @@ if (module === require.main) { Promise.all(args.map((file) => eslint.calculateConfigForFile(file))) .then((configs) => { const rules = [].concat( - ...configs.map((config) => Object.entries(config.rules)) + ...configs.map((config, index) => + Object.entries(config.rules).map((entry) => [...entry, args[index]]) + ) ); const result = processRules(rules); if (result.stderr) { @@ -83,11 +85,13 @@ function processRules(configRules) { ); const flaggedRules = configRules - .map(([ruleName, value]) => { + .map(([ruleName, value, source]) => { const arrayValue = Array.isArray(value) ? value : [value]; const [level, ...options] = arrayValue; const isOff = level === "off" || level === 0; - return !isOff && ruleName in allRules ? { ruleName, options } : null; + return !isOff && ruleName in allRules + ? { ruleName, options, source } + : null; }) .filter(Boolean); @@ -97,8 +101,9 @@ function processRules(configRules) { ); const optionsFlaggedRuleNames = filterRuleNames( flaggedRules, - (ruleName, options) => - ruleName in optionsRules && !validators[ruleName](options) + (ruleName, options, source) => + ruleName in optionsRules && + !validators[ruleName](options, source, configRules) ); const specialFlaggedRuleNames = filterRuleNames( flaggedRules, @@ -177,7 +182,7 @@ function filterRuleNames(rules, fn) { return [ ...new Set( rules - .filter((rule) => fn(rule.ruleName, rule.options)) + .filter((rule) => fn(rule.ruleName, rule.options, rule.source)) .map((rule) => rule.ruleName) ), ]; diff --git a/bin/validators.js b/bin/validators.js index 5646e97..5339d33 100644 --- a/bin/validators.js +++ b/bin/validators.js @@ -4,6 +4,8 @@ // `false` if the options DO conflict with Prettier, and `true` if they don’t. module.exports = { + "arrow-body-style": checkEslintConfigPrettier, + curly(options) { if (options.length === 0) { return true; @@ -48,6 +50,8 @@ module.exports = { return Boolean(firstOption && firstOption.allowIndentationTabs); }, + "prefer-arrow-callback": checkEslintConfigPrettier, + "vue/html-self-closing"(options) { if (options.length === 0) { return false; @@ -61,3 +65,10 @@ module.exports = { ); }, }; + +function checkEslintConfigPrettier(_options, source, rules) { + return !rules.some( + ([name, _options2, source2]) => + name === "prettier/prettier" && source === source2 + ); +} diff --git a/index.js b/index.js index 2cc9d48..a6d9cb1 100644 --- a/index.js +++ b/index.js @@ -7,7 +7,6 @@ module.exports = { // The following rules can be used in some cases. See the README for more // information. (These are marked with `0` instead of `"off"` so that a // script can distinguish them.) - "arrow-body-style": 0, curly: 0, "lines-around-comment": 0, "max-len": 0, @@ -15,7 +14,6 @@ module.exports = { "no-mixed-operators": 0, "no-tabs": 0, "no-unexpected-multiline": 0, - "prefer-arrow-callback": 0, quotes: 0, // The rest are rules that you never need to enable when using Prettier. "array-bracket-newline": "off", diff --git a/package.json b/package.json index 874f470..ec52ee5 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "babel.js", "flowtype.js", "index.js", + "prettier.js", "react.js", "standard.js", "unicorn.js", diff --git a/prettier.js b/prettier.js new file mode 100644 index 0000000..35788e9 --- /dev/null +++ b/prettier.js @@ -0,0 +1,10 @@ +"use strict"; + +module.exports = { + rules: { + // These are safe to use as long as the `"prettier/prettier"` rule from + // eslint-plugin-prettier isn’t enabled. + "arrow-body-style": 0, + "prefer-arrow-callback": 0, + }, +}; diff --git a/test-lint/prettier.js b/test-lint/prettier.js new file mode 100644 index 0000000..1a28a90 --- /dev/null +++ b/test-lint/prettier.js @@ -0,0 +1,14 @@ +/* eslint-disable quotes */ +/* eslint-disable space-before-function-paren */ +"use strict"; + +function foo() { + return ( + isTrue && + [0, 1, 2].map(function (num) { + return num * 2; + }) + ); +} + +foo(); diff --git a/test/cli.test.js b/test/cli.test.js index a907c82..02c72c3 100644 --- a/test/cli.test.js +++ b/test/cli.test.js @@ -12,7 +12,7 @@ function createRules(rules, pattern) { ? arrayPattern.concat(rule.slice(1)) : pattern; const name = Array.isArray(rule) ? rule[0] : rule; - return [name, value]; + return [name, value, "test-source.js"]; }); } @@ -26,11 +26,11 @@ describe("does not flag", () => { test("result", () => { expect(results[0].result).toMatchInlineSnapshot(` -Object { - "code": 0, - "stdout": "No rules that are unnecessary or conflict with Prettier were found.", -} -`); + Object { + "code": 0, + "stdout": "No rules that are unnecessary or conflict with Prettier were found.", + } + `); }); results.forEach(({ pattern, result }) => { @@ -53,13 +53,13 @@ describe("does flag", () => { test("result", () => { expect(results[0].result).toMatchInlineSnapshot(` -Object { - "code": 2, - "stdout": "The following rules are unnecessary or might conflict with Prettier: + Object { + "code": 2, + "stdout": "The following rules are unnecessary or might conflict with Prettier: -- arrow-parens", -} -`); + - arrow-parens", + } + `); }); results.forEach(({ pattern, result }) => { @@ -72,39 +72,39 @@ Object { test("no results", () => { const rules = ["strict", "curly"]; expect(cli.processRules(createRules(rules, "error"))).toMatchInlineSnapshot(` -Object { - "code": 0, - "stdout": "No rules that are unnecessary or conflict with Prettier were found.", -} -`); + Object { + "code": 0, + "stdout": "No rules that are unnecessary or conflict with Prettier were found.", + } + `); }); test("conflicting options", () => { const rules = ["strict", ["curly", "multi-line"]]; expect(cli.processRules(createRules(rules, "error"))).toMatchInlineSnapshot(` -Object { - "code": 2, - "stdout": "The following rules are enabled with options that might conflict with Prettier. See: -https://github.com/prettier/eslint-config-prettier#special-rules - -- curly", -} -`); + Object { + "code": 2, + "stdout": "The following rules are enabled with options that might conflict with Prettier. See: + https://github.com/prettier/eslint-config-prettier#special-rules + + - curly", + } + `); }); test("special rules", () => { const rules = ["strict", "max-len"]; expect(cli.processRules(createRules(rules, "error"))).toMatchInlineSnapshot(` -Object { - "code": 0, - "stdout": "No rules that are unnecessary or conflict with Prettier were found. + Object { + "code": 0, + "stdout": "No rules that are unnecessary or conflict with Prettier were found. -However, the following rules are enabled but cannot be automatically checked. See: -https://github.com/prettier/eslint-config-prettier#special-rules + However, the following rules are enabled but cannot be automatically checked. See: + https://github.com/prettier/eslint-config-prettier#special-rules -- max-len", -} -`); + - max-len", + } + `); }); test("all the things", () => { @@ -131,33 +131,65 @@ test("all the things", () => { "arrow-body-style", ]; expect(cli.processRules(createRules(rules, "error"))).toMatchInlineSnapshot(` -Object { - "code": 2, - "stdout": "The following rules are unnecessary or might conflict with Prettier: - -- arrow-parens -- arrow-spacing -- flowtype/semi -- react/jsx-indent - -The following rules are enabled with options that might conflict with Prettier. See: -https://github.com/prettier/eslint-config-prettier#special-rules - -- curly -- lines-around-comment -- no-confusing-arrow -- no-tabs -- vue/html-self-closing - -The following rules are enabled but cannot be automatically checked. See: -https://github.com/prettier/eslint-config-prettier#special-rules - -- arrow-body-style -- max-len -- no-mixed-operators -- no-unexpected-multiline -- prefer-arrow-callback -- quotes", -} -`); + Object { + "code": 2, + "stdout": "The following rules are unnecessary or might conflict with Prettier: + + - arrow-parens + - arrow-spacing + - flowtype/semi + - react/jsx-indent + + The following rules are enabled with options that might conflict with Prettier. See: + https://github.com/prettier/eslint-config-prettier#special-rules + + - curly + - lines-around-comment + - no-confusing-arrow + - no-tabs + - vue/html-self-closing + + The following rules are enabled but cannot be automatically checked. See: + https://github.com/prettier/eslint-config-prettier#special-rules + + - max-len + - no-mixed-operators + - no-unexpected-multiline + - quotes", + } + `); +}); + +test("eslint-plugin-prettier", () => { + expect( + cli.processRules([ + ["prettier/prettier", "error", "test-source.js"], + ["arrow-body-style", "error", "test-source.js"], + ["prefer-arrow-callback", "error", "test-source.js"], + ]) + ).toMatchInlineSnapshot(` + Object { + "code": 2, + "stdout": "The following rules are enabled with options that might conflict with Prettier. See: + https://github.com/prettier/eslint-config-prettier#special-rules + + - arrow-body-style + - prefer-arrow-callback", + } + `); +}); + +test("eslint-plugin-prettier no warnings because different sources", () => { + expect( + cli.processRules([ + ["prettier/prettier", "error", "test-source.js"], + ["arrow-body-style", "error", "other.js"], + ["prefer-arrow-callback", "error", "other.js"], + ]) + ).toMatchInlineSnapshot(` + Object { + "code": 0, + "stdout": "No rules that are unnecessary or conflict with Prettier were found.", + } + `); }); diff --git a/test/lint-verify-fail.test.js b/test/lint-verify-fail.test.js index c983586..4e0c5c8 100644 --- a/test/lint-verify-fail.test.js +++ b/test/lint-verify-fail.test.js @@ -31,7 +31,10 @@ describe("test-lint/ causes errors without eslint-config-prettier", () => { }); test("must only cause errors related to itself", () => { - if (name === "index") { + // ESLint core rules have no prefix. + // eslint-plugin-prettier provides no conflicting rules, but makes two + // core rules unusable. + if (name === "index" || name === "prettier") { expect( ruleIds .filter((ruleId) => ruleId.includes("/")) From 4d08b847cb2cb808b22f6044944ac0a619c9226a Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Sun, 29 Nov 2020 19:11:14 +0100 Subject: [PATCH 06/11] Reduce npm package size by 75% --- .eslintignore | 1 + .eslintrc.base.js | 10 ++++++--- .eslintrc.js | 7 +++--- .github/workflows/check.yml | 3 +++ .gitignore | 1 + .prettierignore | 1 + README.md | 3 +-- package-real.json | 13 +++++++++++ package.json | 32 +++----------------------- scripts/build.js | 45 +++++++++++++++++++++++++++++++++++++ test/rules.test.js | 9 -------- 11 files changed, 79 insertions(+), 46 deletions(-) create mode 100644 package-real.json create mode 100644 scripts/build.js diff --git a/.eslintignore b/.eslintignore index 0f8b6ec..3f593a7 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,3 @@ !/.* +/build/ /test-config/ diff --git a/.eslintrc.base.js b/.eslintrc.base.js index e3697df..7881467 100644 --- a/.eslintrc.base.js +++ b/.eslintrc.base.js @@ -1,6 +1,6 @@ "use strict"; -const pkg = require("./package.json"); +const fs = require("fs"); module.exports = { extends: [ @@ -12,8 +12,12 @@ module.exports = { ], plugins: [ "prettier", - ...pkg.files - .filter((name) => !name.includes("/") && name !== "index.js") + ...fs + .readdirSync(__dirname) + .filter( + (file) => + !file.startsWith(".") && file.endsWith(".js") && file !== "index.js" + ) .map((ruleFileName) => ruleFileName.replace(/\.js$/, "")), ], parserOptions: { diff --git a/.eslintrc.js b/.eslintrc.js index 63b3059..2bbbc12 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,12 +1,13 @@ "use strict"; -const pkg = require("./package.json"); +const fs = require("fs"); module.exports = { extends: [ "./.eslintrc.base.js", - ...pkg.files - .filter((name) => !name.includes("/")) + ...fs + .readdirSync(__dirname) + .filter((file) => !file.startsWith(".") && file.endsWith(".js")) .map((ruleFileName) => `./${ruleFileName}`), ], rules: { diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 47f3602..3bacd41 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -38,3 +38,6 @@ jobs: - name: Prettier run: npx --no-install prettier --check . + + - name: Build + run: npm run build diff --git a/.gitignore b/.gitignore index 9e4b161..fbad133 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +/build/ /node_modules/ /test-config/ diff --git a/.prettierignore b/.prettierignore index 2f50b84..d61e61b 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,2 +1,3 @@ +/build/ /test-config/ .vscode diff --git a/README.md b/README.md index 258a73c..1c052e4 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This lets you use your favorite shareable config without letting its stylistic c Note that this config _only_ turns rules _off,_ so it only makes sense using it together with some other config. -## Contents +--- @@ -786,7 +786,6 @@ console.log(); Finally, you need to mention the plugin in several places: -- Add `"foobar.js"` to the "files" field in `package.json`. - Add eslint-plugin-foobar to the "devDependencies" field in `package.json`. - Make sure that at least one rule from eslint-plugin-foobar gets used in `.eslintrc.base.js`. - Add it to the list of supported plugins and to the Contributing section in `README.md`. diff --git a/package-real.json b/package-real.json new file mode 100644 index 0000000..43d346c --- /dev/null +++ b/package-real.json @@ -0,0 +1,13 @@ +{ + "name": "eslint-config-prettier", + "version": "6.15.0", + "license": "MIT", + "author": "Simon Lydell", + "description": "Turns off all rules that are unnecessary or might conflict with Prettier.", + "repository": "prettier/eslint-config-prettier", + "bin": "bin/cli.js", + "keywords": ["eslint", "eslintconfig", "prettier"], + "peerDependencies": { + "eslint": ">=7.0.0" + } +} diff --git a/package.json b/package.json index ec52ee5..d2868ad 100644 --- a/package.json +++ b/package.json @@ -1,28 +1,5 @@ { - "name": "eslint-config-prettier", - "version": "6.15.0", - "license": "MIT", - "author": "Simon Lydell", - "description": "Turns off all rules that are unnecessary or might conflict with Prettier.", - "repository": "prettier/eslint-config-prettier", - "files": [ - "bin/", - "@typescript-eslint.js", - "babel.js", - "flowtype.js", - "index.js", - "prettier.js", - "react.js", - "standard.js", - "unicorn.js", - "vue.js" - ], - "bin": "bin/cli.js", - "keywords": [ - "eslint", - "eslintconfig", - "prettier" - ], + "private": true, "scripts": { "doctoc": "doctoc README.md && replace \"\\[\\[([\\w/-]+)\\](?:([^\\[\\]]+)\\[([\\w/-]+)\\])?\\]\" \"[\\$1\\$2\\$3]\" README.md", "prettier": "prettier --write .", @@ -33,9 +10,9 @@ "test:jest": "jest", "test:cli-sanity": "node ./bin/cli.js index.js", "test:cli-sanity-warning": "node ./bin/cli.js react.js ./bin/cli.js", - "test": "npm run test:lint && npm run test:jest && npm run test:cli-sanity && npm run test:cli-sanity-warning" + "test": "npm run test:lint && npm run test:jest && npm run test:cli-sanity && npm run test:cli-sanity-warning && npm run build", + "build": "node scripts/build.js" }, - "dependencies": {}, "devDependencies": { "@typescript-eslint/eslint-plugin": "4.8.2", "@typescript-eslint/parser": "4.8.2", @@ -56,8 +33,5 @@ "replace": "1.2.0", "rimraf": "3.0.2", "typescript": "4.1.2" - }, - "peerDependencies": { - "eslint": ">=7.0.0" } } diff --git a/scripts/build.js b/scripts/build.js new file mode 100644 index 0000000..8642d8c --- /dev/null +++ b/scripts/build.js @@ -0,0 +1,45 @@ +"use strict"; + +const fs = require("fs"); +const path = require("path"); + +const DIR = path.join(__dirname, ".."); +const BUILD = path.join(DIR, "build"); + +const READ_MORE = + "**[➡️ Full readme](https://github.com/prettier/eslint-config-prettier/)**"; + +const FILES_TO_COPY = [ + { src: "LICENSE" }, + { src: "package-real.json", dest: "package.json" }, + { + src: "README.md", + transform: (content) => content.replace(/^---[^]*/m, READ_MORE), + }, + ...fs + .readdirSync(path.join(DIR, "bin")) + .filter((file) => !file.startsWith(".") && file.endsWith(".js")) + .map((file) => ({ src: path.join("bin", file) })), + ...fs + .readdirSync(DIR) + .filter((file) => !file.startsWith(".") && file.endsWith(".js")) + .map((file) => ({ src: file })), +]; + +if (fs.existsSync(BUILD)) { + fs.rmdirSync(BUILD, { recursive: true }); +} + +fs.mkdirSync(BUILD); + +for (const { src, dest = src, transform } of FILES_TO_COPY) { + if (transform) { + fs.writeFileSync( + path.join(BUILD, dest), + transform(fs.readFileSync(path.join(DIR, src), "utf8")) + ); + } else { + fs.mkdirSync(path.dirname(path.join(BUILD, dest)), { recursive: true }); + fs.copyFileSync(path.join(DIR, src), path.join(BUILD, dest)); + } +} diff --git a/test/rules.test.js b/test/rules.test.js index 84e52ae..8632acd 100644 --- a/test/rules.test.js +++ b/test/rules.test.js @@ -4,7 +4,6 @@ const childProcess = require("child_process"); const fs = require("fs"); const path = require("path"); const rimraf = require("rimraf"); -const pkg = require("../package.json"); const eslintConfig = require("../.eslintrc"); const eslintConfigBase = require("../.eslintrc.base"); @@ -55,14 +54,6 @@ function createTestConfigDir() { }); } -describe("all rule files are listed in package.json", () => { - ruleFiles.forEach((ruleFileName) => { - test(ruleFileName, () => { - expect(pkg.files).toContain(ruleFileName); - }); - }); -}); - describe("all rule files have tests in test-lint/", () => { ruleFiles.forEach((ruleFileName) => { test(ruleFileName, () => { From dcba135eb09ece415a892733c104c8992670d2ec Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Mon, 30 Nov 2020 21:43:36 +0100 Subject: [PATCH 07/11] Remove docs moved to eslint-plugin-prettier --- README.md | 82 ++++++----------------------------------------------- prettier.js | 2 ++ 2 files changed, 11 insertions(+), 73 deletions(-) diff --git a/README.md b/README.md index 1c052e4..bd4e6a9 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,6 @@ Note that this config _only_ turns rules _off,_ so it only makes sense using it - [Installation](#installation) - - [eslint-plugin-prettier](#eslint-plugin-prettier) - [Excluding deprecated rules](#excluding-deprecated-rules) - [CLI helper tool](#cli-helper-tool) - [Legacy](#legacy) @@ -104,54 +103,6 @@ If you extend a config which uses a plugin, it is recommended to add `"prettier/ If you’re unsure which plugins are used, you can usually find them in your `package.json`. -### eslint-plugin-prettier - -In the above section you might have noticed this plugin being mentioned: - -[eslint-plugin-prettier][eslint-plugin-prettier] - -Just to clear any confusion, the repo you’re currently looking at is: - -eslint-config-prettier - -So what’s the difference? - -- eslint-plugin-prettier adds a new _rule_ that lets you run Prettier from within ESLint as if it was a regular old ESLint rule. -- eslint-config-prettier just turns off a bunch of rules (that are unnecessary or conflict with Prettier). - -To make things even more confusing, eslint-plugin-prettier _also_ provides a _config_ you can extend. It’s called `"plugin:prettier/recommended"`. All that config does is: - -```json -{ - "extends": ["prettier", "prettier/prettier"], - "plugins": ["prettier"], - "rules": { - "prettier/prettier": "error" - } -} -``` - -Ugh, that’s a lot of `prettier` and `prettier/prettier`! What is all of that doing? Let’s start from the bottom: - -- `"rules": { "prettier/prettier": "error" }` turns on the _rule_ that eslint-plugin-prettier provides, that lets you run Prettier from within ESLint. - -- `"plugins": ["prettier"]` registers eslint-plugin-prettier as a plugin, so ESLint knows what `"prettier/prettier": "error"` is. - -- `"extends"` is the interesting part. This requires you to also install eslint-config-prettier (this repo), because the listed configs comes from _this_ repo, not from the plugin’s repo! - - - `"prettier"` is the base config which disables ESLint core rules. - - `"prettier/prettier"` is specific config for eslint-plugin-prettier which disables [two ESLint core rules][eslint-plugin-prettier-special] that conflict only with eslint-plugin-prettier (not Prettier itself). - -Note that even if you use `"plugin:prettier/recommended"`, you might still need to add more stuff to the `"extends"` array, depending on which other plugins you use. For example: - -```json -{ - "extends": ["plugin:prettier/recommended", "prettier/@typescript-eslint"] -} -``` - -**Note:** [eslint-plugin-prettier has some downsides][eslint-plugin-prettier-downsides] that you might want to read about. - ### Excluding deprecated rules Some of the rules that eslint-config-prettier turns off may be deprecated. **This is perfectly fine,** but if you really need to omit the deprecated rules, you can do so by setting the `ESLINT_CONFIG_PRETTIER_NO_DEPRECATED` environment variable to a non-empty value. For example: @@ -212,29 +163,18 @@ For maximum ease of use, the special rules are disabled by default (provided tha **These rules might cause problems if using [eslint-plugin-prettier] and `--fix`.** -If you use any of these rules together with the `prettier/prettier` rule from [eslint-plugin-prettier], you can in some cases end up with invalid code due to a bug in ESLint’s autofix. - -These rules are safe to use if: - -- You don’t use [eslint-plugin-prettier]. In other words, you run `eslint --fix` and `prettier --write` as separate steps. -- You _do_ use [eslint-plugin-prettier], but don’t use `--fix`. (But then, what’s the point?) - -You _can_ still use these rules together with [eslint-plugin-prettier] if you want, because the bug does not occur _all the time._ But if you do, you need to keep in mind that you might end up with invalid code, where you manually have to insert a missing closing parenthesis to get going again. +See [`arrow-body-style` and `prefer-arrow-callback` issue][eslint-plugin-prettier-autofix-issue] for details. -If you’re fixing large of amounts of previously unformatted code, consider temporarily disabling the `prettier/prettier` rule and running `eslint --fix` and `prettier --write` separately. +There are a couple of ways to turn these rules off: -See these issues for more information: - -- [eslint-config-prettier#31] -- [eslint-config-prettier#71] -- [eslint-plugin-prettier#65] - -When the autofix bug in ESLint has been fixed, the special case for these rules can be removed. - -Note: You need to put `"prettier/prettier"` in your `"extends"` array if you want these rules to be turned off. (Yes, there’s both a _rule_ called `"prettier/prettier"` and a _config_ called `"prettier/prettier"`.) +- Put `"prettier/prettier"` in your `"extends"`. (Yes, there’s both a _rule_ called `"prettier/prettier"` and a _config_ called `"prettier/prettier"`.) +- Use [eslint-plugin-prettier’s recommended config][eslint-plugin-prettier-recommended], which also turns off these two rules. +- Remove them from your config or turn them off manually. Note: The CLI tool only reports these as problematic if the `"prettier/prettier"` _rule_ is enabled for the same file. +These rules are safe to use if you don’t use [eslint-plugin-prettier]. In other words, if you run `eslint --fix` and `prettier --write` as separate steps. + ### [curly] **This rule requires certain options.** @@ -810,16 +750,12 @@ When you’re done, run `npm test` to verify that you got it all right. It runs [arrow-body-style]: https://eslint.org/docs/rules/arrow-body-style [babel/quotes]: https://github.com/babel/eslint-plugin-babel#rules [curly]: https://eslint.org/docs/rules/curly -[eslint 5.7.0]: https://eslint.org/blog/2018/10/eslint-v5.7.0-released [eslint-config-airbnb]: https://www.npmjs.com/package/eslint-config-airbnb -[eslint-config-prettier#31]: https://github.com/prettier/eslint-config-prettier/issues/31 -[eslint-config-prettier#71]: https://github.com/prettier/eslint-config-prettier/issues/71 [eslint-plugin-babel]: https://github.com/babel/eslint-plugin-babel [eslint-plugin-flowtype]: https://github.com/gajus/eslint-plugin-flowtype -[eslint-plugin-prettier-downsides]: https://prettier.io/docs/en/integrating-with-linters.html#notes -[eslint-plugin-prettier-special]: #arrow-body-style-and-prefer-arrow-callback +[eslint-plugin-prettier-autofix-issue]: https://github.com/prettier/eslint-plugin-prettier#arrow-body-style-and-prefer-arrow-callback-issue +[eslint-plugin-prettier-recommended]: https://github.com/prettier/eslint-plugin-prettier#recommended-configuration [eslint-plugin-prettier]: https://github.com/prettier/eslint-plugin-prettier -[eslint-plugin-prettier#65]: https://github.com/prettier/eslint-plugin-prettier/issues/65 [eslint-plugin-react]: https://github.com/yannickcr/eslint-plugin-react [eslint-plugin-standard]: https://github.com/xjamundx/eslint-plugin-standard [eslint-plugin-unicorn]: https://github.com/sindresorhus/eslint-plugin-unicorn diff --git a/prettier.js b/prettier.js index 35788e9..aac873c 100644 --- a/prettier.js +++ b/prettier.js @@ -4,6 +4,8 @@ module.exports = { rules: { // These are safe to use as long as the `"prettier/prettier"` rule from // eslint-plugin-prettier isn’t enabled. + // These are also included in `"plugin:prettier/recommended"`: + // https://github.com/prettier/eslint-plugin-prettier#recommended-configuration "arrow-body-style": 0, "prefer-arrow-callback": 0, }, From bc65d4380007e75f17ea6dbc6f1c849dc0ed74f6 Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Mon, 30 Nov 2020 21:55:16 +0100 Subject: [PATCH 08/11] =?UTF-8?q?Don=E2=80=99t=20warn=20about=20eslint-plu?= =?UTF-8?q?gin-prettier=20rules=20if=20prettier/prettier=20is=20off?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bin/cli.js | 12 +++++++----- bin/validators.js | 8 ++++---- test/cli.test.js | 15 +++++++++++++++ 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/bin/cli.js b/bin/cli.js index f649336..a349193 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -84,17 +84,19 @@ function processRules(configRules) { (ruleName, value) => value === 0 && !(ruleName in validators) ); - const flaggedRules = configRules + const enabledRules = configRules .map(([ruleName, value, source]) => { const arrayValue = Array.isArray(value) ? value : [value]; const [level, ...options] = arrayValue; const isOff = level === "off" || level === 0; - return !isOff && ruleName in allRules - ? { ruleName, options, source } - : null; + return isOff ? null : { ruleName, options, source }; }) .filter(Boolean); + const flaggedRules = enabledRules.filter( + ({ ruleName }) => ruleName in allRules + ); + const regularFlaggedRuleNames = filterRuleNames( flaggedRules, (ruleName) => ruleName in regularRules @@ -103,7 +105,7 @@ function processRules(configRules) { flaggedRules, (ruleName, options, source) => ruleName in optionsRules && - !validators[ruleName](options, source, configRules) + !validators[ruleName](options, source, enabledRules) ); const specialFlaggedRuleNames = filterRuleNames( flaggedRules, diff --git a/bin/validators.js b/bin/validators.js index 5339d33..4c89221 100644 --- a/bin/validators.js +++ b/bin/validators.js @@ -66,9 +66,9 @@ module.exports = { }, }; -function checkEslintConfigPrettier(_options, source, rules) { - return !rules.some( - ([name, _options2, source2]) => - name === "prettier/prettier" && source === source2 +function checkEslintConfigPrettier(_options, currentSource, enabledRules) { + return !enabledRules.some( + ({ ruleName, source }) => + ruleName === "prettier/prettier" && currentSource === source ); } diff --git a/test/cli.test.js b/test/cli.test.js index 02c72c3..6971758 100644 --- a/test/cli.test.js +++ b/test/cli.test.js @@ -193,3 +193,18 @@ test("eslint-plugin-prettier no warnings because different sources", () => { } `); }); + +test("eslint-plugin-prettier no warnings because the rule is off", () => { + expect( + cli.processRules([ + ["prettier/prettier", [0, {}], "test-source.js"], + ["arrow-body-style", "error", "test-source.js"], + ["prefer-arrow-callback", "error", "test-source.js"], + ]) + ).toMatchInlineSnapshot(` + Object { + "code": 0, + "stdout": "No rules that are unnecessary or conflict with Prettier were found.", + } + `); +}); From 7642c5824da662931203478aace160a85b40839f Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Mon, 30 Nov 2020 21:57:00 +0100 Subject: [PATCH 09/11] Make error message fit better for eslint-plugin-prettier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s not about the rule’s options, it’s about other config (another rules being enabled). --- bin/cli.js | 2 +- test/cli.test.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/cli.js b/bin/cli.js index a349193..e0da87d 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -144,7 +144,7 @@ function processRules(configRules) { ].join("\n"); const optionsMessage = [ - "The following rules are enabled with options that might conflict with Prettier. See:", + "The following rules are enabled with config that might conflict with Prettier. See:", SPECIAL_RULES_URL, "", printRuleNames(optionsFlaggedRuleNames), diff --git a/test/cli.test.js b/test/cli.test.js index 6971758..1b6d888 100644 --- a/test/cli.test.js +++ b/test/cli.test.js @@ -84,7 +84,7 @@ test("conflicting options", () => { expect(cli.processRules(createRules(rules, "error"))).toMatchInlineSnapshot(` Object { "code": 2, - "stdout": "The following rules are enabled with options that might conflict with Prettier. See: + "stdout": "The following rules are enabled with config that might conflict with Prettier. See: https://github.com/prettier/eslint-config-prettier#special-rules - curly", @@ -140,7 +140,7 @@ test("all the things", () => { - flowtype/semi - react/jsx-indent - The following rules are enabled with options that might conflict with Prettier. See: + The following rules are enabled with config that might conflict with Prettier. See: https://github.com/prettier/eslint-config-prettier#special-rules - curly @@ -170,7 +170,7 @@ test("eslint-plugin-prettier", () => { ).toMatchInlineSnapshot(` Object { "code": 2, - "stdout": "The following rules are enabled with options that might conflict with Prettier. See: + "stdout": "The following rules are enabled with config that might conflict with Prettier. See: https://github.com/prettier/eslint-config-prettier#special-rules - arrow-body-style From 0d0b1ac58956e902d31278dfdf6652be6ada4227 Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Mon, 30 Nov 2020 22:24:24 +0100 Subject: [PATCH 10/11] Fix local eslint require --- bin/cli.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/bin/cli.js b/bin/cli.js index e0da87d..9e16cfb 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -4,9 +4,14 @@ const fs = require("fs"); const path = require("path"); -const { ESLint } = require("eslint"); const validators = require("./validators"); +// Require locally installed eslint, for `npx eslint-config-prettier` support +// with no local eslint-config-prettier installation. +const { ESLint } = require(require.resolve("eslint", { + paths: [process.cwd(), ...require.resolve.paths("eslint")], +})); + const SPECIAL_RULES_URL = "https://github.com/prettier/eslint-config-prettier#special-rules"; From f0b8764fd5c9fb9df38f9d7e4b4f6ad42037dca9 Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Sat, 5 Dec 2020 22:33:57 +0100 Subject: [PATCH 11/11] Various cleanups --- .eslintrc.base.js | 3 +++ .eslintrc.js | 6 ++++++ README.md | 1 + bin/cli.js | 15 +++++---------- bin/validators.js | 16 ++++++++-------- package-lock.json | 4 +--- test/validators.test.js | 10 +++++----- 7 files changed, 29 insertions(+), 26 deletions(-) diff --git a/.eslintrc.base.js b/.eslintrc.base.js index 7881467..b4d1e13 100644 --- a/.eslintrc.base.js +++ b/.eslintrc.base.js @@ -1,5 +1,8 @@ "use strict"; +// This file is only used in `./.eslintrc.js` and in the tests – it’s not part +// of the eslint-config-prettier npm package. + const fs = require("fs"); module.exports = { diff --git a/.eslintrc.js b/.eslintrc.js index 2bbbc12..83181a0 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,5 +1,11 @@ "use strict"; +// This is the internal ESLint config for this project itself – it’s not part of +// the eslint-config-prettier npm package. The idea here is to extends some +// sharable config from npm and then include the configs exposed by this package +// as an “eat your own dogfood” test. That feels like a good test, but +// complicates things a little sometimes. + const fs = require("fs"); module.exports = { diff --git a/README.md b/README.md index bd4e6a9..b3c5fd1 100644 --- a/README.md +++ b/README.md @@ -679,6 +679,7 @@ You can also supply a custom message if you want: eslint-config-prettier has been tested with: - ESLint 7.14.0 + - eslint-config-prettier 7.0.0 requires ESLint 7.0.0 or newer, while eslint-config-prettier 6.15.0 and older should also work with ESLint versions down to 3.x. - eslint-config-prettier 6.11.0 and older were tested with ESLint 6.x - eslint-config-prettier 5.1.0 and older were tested with ESLint 5.x - eslint-config-prettier 2.10.0 and older were tested with ESLint 4.x diff --git a/bin/cli.js b/bin/cli.js index 9e16cfb..8d5d74e 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -104,17 +104,16 @@ function processRules(configRules) { const regularFlaggedRuleNames = filterRuleNames( flaggedRules, - (ruleName) => ruleName in regularRules + ({ ruleName }) => ruleName in regularRules ); const optionsFlaggedRuleNames = filterRuleNames( flaggedRules, - (ruleName, options, source) => - ruleName in optionsRules && - !validators[ruleName](options, source, enabledRules) + ({ ruleName, ...rule }) => + ruleName in optionsRules && !validators[ruleName](rule, enabledRules) ); const specialFlaggedRuleNames = filterRuleNames( flaggedRules, - (ruleName) => ruleName in specialRules + ({ ruleName }) => ruleName in specialRules ); if ( @@ -187,11 +186,7 @@ function filterRules(rules, fn) { function filterRuleNames(rules, fn) { return [ - ...new Set( - rules - .filter((rule) => fn(rule.ruleName, rule.options, rule.source)) - .map((rule) => rule.ruleName) - ), + ...new Set(rules.filter((rule) => fn(rule)).map((rule) => rule.ruleName)), ]; } diff --git a/bin/validators.js b/bin/validators.js index 4c89221..ef3eab4 100644 --- a/bin/validators.js +++ b/bin/validators.js @@ -4,9 +4,9 @@ // `false` if the options DO conflict with Prettier, and `true` if they don’t. module.exports = { - "arrow-body-style": checkEslintConfigPrettier, + "arrow-body-style": checkEslintPluginPrettier, - curly(options) { + curly({ options }) { if (options.length === 0) { return true; } @@ -15,7 +15,7 @@ module.exports = { return firstOption !== "multi-line" && firstOption !== "multi-or-nest"; }, - "lines-around-comment"(options) { + "lines-around-comment"({ options }) { if (options.length === 0) { return false; } @@ -32,7 +32,7 @@ module.exports = { ); }, - "no-confusing-arrow"(options) { + "no-confusing-arrow"({ options }) { if (options.length === 0) { return false; } @@ -41,7 +41,7 @@ module.exports = { return firstOption ? firstOption.allowParens === false : false; }, - "no-tabs"(options) { + "no-tabs"({ options }) { if (options.length === 0) { return false; } @@ -50,9 +50,9 @@ module.exports = { return Boolean(firstOption && firstOption.allowIndentationTabs); }, - "prefer-arrow-callback": checkEslintConfigPrettier, + "prefer-arrow-callback": checkEslintPluginPrettier, - "vue/html-self-closing"(options) { + "vue/html-self-closing"({ options }) { if (options.length === 0) { return false; } @@ -66,7 +66,7 @@ module.exports = { }, }; -function checkEslintConfigPrettier(_options, currentSource, enabledRules) { +function checkEslintPluginPrettier({ source: currentSource }, enabledRules) { return !enabledRules.some( ({ ruleName, source }) => ruleName === "prettier/prettier" && currentSource === source diff --git a/package-lock.json b/package-lock.json index e747aed..3282e06 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,8 +1,6 @@ { - "name": "eslint-config-prettier", - "version": "6.15.0", - "lockfileVersion": 1, "requires": true, + "lockfileVersion": 1, "dependencies": { "@babel/code-frame": { "version": "7.10.4", diff --git a/test/validators.test.js b/test/validators.test.js index 52cb24f..71a6feb 100644 --- a/test/validators.test.js +++ b/test/validators.test.js @@ -4,11 +4,11 @@ const validators = require("../bin/validators"); const { inspect } = require("util"); expect.extend({ - toPass(validator, opts) { - const pass = validator(opts); + toPass(validator, options) { + const pass = validator({ options, source: "test-source.js" }, []); return { message: () => - `expected ${inspect(opts)} to be ${pass ? "invalid" : "valid"}`, + `expected ${inspect(options)} to be ${pass ? "invalid" : "valid"}`, pass, }; }, @@ -17,8 +17,8 @@ expect.extend({ function rule(name, { valid, invalid }) { test(name, () => { const validator = validators[name]; - valid.forEach((opts) => expect(validator).toPass(opts)); - invalid.forEach((opts) => expect(validator).not.toPass(opts)); + valid.forEach((options) => expect(validator).toPass(options)); + invalid.forEach((options) => expect(validator).not.toPass(options)); }); }