Skip to content

Commit

Permalink
One config to rule them all (#175)
Browse files Browse the repository at this point in the history
Fixes #173. Fixes #174.
  • Loading branch information
lydell authored Feb 21, 2021
1 parent 72ce4d7 commit 03c79b9
Show file tree
Hide file tree
Showing 19 changed files with 271 additions and 351 deletions.
19 changes: 9 additions & 10 deletions .eslintrc.base.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// 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");
const config = require(".");

module.exports = {
extends: [
Expand All @@ -15,13 +15,12 @@ module.exports = {
],
plugins: [
"prettier",
...fs
.readdirSync(__dirname)
.filter(
(file) =>
!file.startsWith(".") && file.endsWith(".js") && file !== "index.js"
)
.map((ruleFileName) => ruleFileName.replace(/\.js$/, "")),
...new Set(
Object.keys(config.rules)
.map((ruleName) => ruleName.split("/"))
.filter((parts) => parts.length > 1)
.map((parts) => parts[0])
),
],
parserOptions: {
parser: "babel-eslint",
Expand All @@ -38,10 +37,10 @@ module.exports = {
node: true,
},
rules: {
indent: "off",
"indent": "off",
"linebreak-style": "off",
"no-dupe-keys": "error",
strict: "error",
"strict": "error",
"prefer-spread": "off",
"require-jsdoc": "off",
"prettier/prettier": "error",
Expand Down
12 changes: 2 additions & 10 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,8 @@
// 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 = {
extends: [
"./.eslintrc.base.js",
...fs
.readdirSync(__dirname)
.filter((file) => !file.startsWith(".") && file.endsWith(".js"))
.map((ruleFileName) => `./${ruleFileName}`),
],
extends: ["./.eslintrc.base.js", "./index.js", "./prettier.js"],
rules: {
"prettier/prettier": "off",
},
Expand All @@ -32,7 +24,7 @@ module.exports = {
"The comma operator is confusing and a common mistake. Don’t use it!",
},
],
quotes: [
"quotes": [
"error",
"double",
{ avoidEscape: true, allowTemplateLiterals: false },
Expand Down
3 changes: 2 additions & 1 deletion .prettierrc.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"proseWrap": "never"
"proseWrap": "never",
"quoteProps": "consistent"
}
22 changes: 0 additions & 22 deletions @typescript-eslint.js

This file was deleted.

54 changes: 8 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Then, add eslint-config-prettier to the "extends" array in your `.eslintrc.*` fi
}
```

A few ESLint plugins are supported as well:
That’s it! Extending `"prettier"` turns off a bunch of core ESLint rules, as well as a few rules from these plugins:

- [@typescript-eslint/eslint-plugin]
- [eslint-plugin-babel]
Expand All @@ -68,40 +68,7 @@ A few ESLint plugins are supported as well:
- [eslint-plugin-unicorn]
- [eslint-plugin-vue]

Add extra exclusions for the plugins you use like so:

<!-- prettier-ignore -->
```json
{
"extends": [
"some-other-config-you-use",
"prettier",
"prettier/@typescript-eslint",
"prettier/babel",
"prettier/flowtype",
"prettier/prettier",
"prettier/react",
"prettier/standard",
"prettier/unicorn",
"prettier/vue"
]
}
```

If you extend a config which uses a plugin, it is recommended to add `"prettier/that-plugin"` (if available). For example, [eslint-config-airbnb] enables [eslint-plugin-react] rules, so `"prettier/react"` is needed:

<!-- prettier-ignore -->
```json
{
"extends": [
"airbnb",
"prettier",
"prettier/react"
]
}
```

If you’re unsure which plugins are used, you can usually find them in your `package.json`.
> Note: You might find guides on the Internet saying you should also extend stuff like `"prettier/react"`. Since version 8.0.0 of eslint-config-prettier, all you need to extend is `"prettier"`! That includes all plugins.
### Excluding deprecated rules

Expand Down Expand Up @@ -163,14 +130,16 @@ 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`.**

See [`arrow-body-style` and `prefer-arrow-callback` issue][eslint-plugin-prettier-autofix-issue] for details.
See the [`arrow-body-style` and `prefer-arrow-callback` issue][eslint-plugin-prettier-autofix-issue] for details.

There are a couple of ways to turn these rules off:

- 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.

It doesn’t matter which approach you use – they’re all the same.

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.
Expand Down Expand Up @@ -698,17 +667,11 @@ Have new rules been added since those versions? Have we missed any rules? Is the

If you’d like to add support for eslint-plugin-foobar, this is how you’d go about it:

First, create `foobar.js`:
First, add rules to `index.js`:

<!-- prettier-ignore -->
```js
"use strict";

module.exports = {
rules: {
"foobar/some-rule": "off"
}
};
"foobar/some-rule": "off"
```

Then, create `test-lint/foobar.js`:
Expand All @@ -729,7 +692,7 @@ Finally, you need to mention the plugin in several places:

- 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`.
- Add it to the lists of supported plugins and in this `README.md`.

When you’re done, run `npm test` to verify that you got it all right. It runs several other npm scripts:

Expand All @@ -751,7 +714,6 @@ 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-config-airbnb]: https://www.npmjs.com/package/eslint-config-airbnb
[eslint-plugin-babel]: https://github.com/babel/eslint-plugin-babel
[eslint-plugin-flowtype]: https://github.com/gajus/eslint-plugin-flowtype
[eslint-plugin-prettier-autofix-issue]: https://github.com/prettier/eslint-plugin-prettier#arrow-body-style-and-prefer-arrow-callback-issue
Expand Down
10 changes: 0 additions & 10 deletions babel.js

This file was deleted.

97 changes: 52 additions & 45 deletions bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

"use strict";

const fs = require("fs");
const path = require("path");
const validators = require("./validators");
const config = require("..");
const prettier = require("../prettier");

// Require locally installed eslint, for `npx eslint-config-prettier` support
// with no local eslint-config-prettier installation.
Expand All @@ -15,6 +15,9 @@ const { ESLint } = require(require.resolve("eslint", {
const SPECIAL_RULES_URL =
"https://github.com/prettier/eslint-config-prettier#special-rules";

const PRETTIER_RULES_URL =
"https://github.com/prettier/eslint-config-prettier#arrow-body-style-and-prefer-arrow-callback";

if (module === require.main) {
const args = process.argv.slice(2);

Expand All @@ -28,8 +31,8 @@ if (module === require.main) {
Promise.all(args.map((file) => eslint.calculateConfigForFile(file)))
.then((configs) => {
const rules = [].concat(
...configs.map((config, index) =>
Object.entries(config.rules).map((entry) => [...entry, args[index]])
...configs.map(({ rules }, index) =>
Object.entries(rules).map((entry) => [...entry, args[index]])
)
);
const result = processRules(rules);
Expand Down Expand Up @@ -68,24 +71,13 @@ https://github.com/prettier/eslint-config-prettier#cli-helper-tool
}

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
const allRules = Object.assign(
Object.create(null),
...fs
.readdirSync(path.join(__dirname, ".."))
.filter((name) => !name.startsWith(".") && name.endsWith(".js"))
.map((ruleFileName) => require(`../${ruleFileName}`).rules)
);

const regularRules = filterRules(allRules, (_, value) => value === "off");
const regularRules = filterRules(config.rules, (_, value) => value === "off");
const optionsRules = filterRules(
allRules,
config.rules,
(ruleName, value) => value === 0 && ruleName in validators
);
const specialRules = filterRules(
allRules,
config.rules,
(ruleName, value) => value === 0 && !(ruleName in validators)
);

Expand All @@ -99,7 +91,7 @@ function processRules(configRules) {
.filter(Boolean);

const flaggedRules = enabledRules.filter(
({ ruleName }) => ruleName in allRules
({ ruleName }) => ruleName in config.rules
);

const regularFlaggedRuleNames = filterRuleNames(
Expand All @@ -109,37 +101,21 @@ function processRules(configRules) {
const optionsFlaggedRuleNames = filterRuleNames(
flaggedRules,
({ ruleName, ...rule }) =>
ruleName in optionsRules && !validators[ruleName](rule, enabledRules)
ruleName in optionsRules && !validators[ruleName](rule)
);
const specialFlaggedRuleNames = filterRuleNames(
flaggedRules,
({ ruleName }) => ruleName in specialRules
);

if (
regularFlaggedRuleNames.length === 0 &&
optionsFlaggedRuleNames.length === 0
) {
const baseMessage =
"No rules that are unnecessary or conflict with Prettier were found.";

const message =
specialFlaggedRuleNames.length === 0
? baseMessage
: [
baseMessage,
"",
"However, the following rules are enabled but cannot be automatically checked. See:",
SPECIAL_RULES_URL,
"",
printRuleNames(specialFlaggedRuleNames),
].join("\n");

return {
stdout: message,
code: 0,
};
}
const prettierFlaggedRuleNames = filterRuleNames(
enabledRules,
({ ruleName, source }) =>
ruleName in prettier.rules &&
enabledRules.some(
(rule) =>
rule.ruleName === "prettier/prettier" && rule.source === source
)
);

const regularMessage = [
"The following rules are unnecessary or might conflict with Prettier:",
Expand All @@ -161,10 +137,41 @@ function processRules(configRules) {
printRuleNames(specialFlaggedRuleNames),
].join("\n");

const prettierMessage = [
"The following rules can cause issues when using eslint-plugin-prettier at the same time.",
"Only enable them if you know what you are doing! See:",
PRETTIER_RULES_URL,
"",
printRuleNames(prettierFlaggedRuleNames),
].join("\n");

if (
regularFlaggedRuleNames.length === 0 &&
optionsFlaggedRuleNames.length === 0
) {
const message =
specialFlaggedRuleNames.length === 0 &&
prettierFlaggedRuleNames.length === 0
? "No rules that are unnecessary or conflict with Prettier were found."
: [
specialFlaggedRuleNames.length === 0 ? null : specialMessage,
prettierFlaggedRuleNames.length === 0 ? null : prettierMessage,
"Other than that, no rules that are unnecessary or conflict with Prettier were found.",
]
.filter(Boolean)
.join("\n\n");

return {
stdout: message,
code: 0,
};
}

const message = [
regularFlaggedRuleNames.length === 0 ? null : regularMessage,
optionsFlaggedRuleNames.length === 0 ? null : optionsMessage,
specialFlaggedRuleNames.length === 0 ? null : specialMessage,
prettierFlaggedRuleNames.length === 0 ? null : prettierMessage,
]
.filter(Boolean)
.join("\n\n");
Expand Down
Loading

0 comments on commit 03c79b9

Please sign in to comment.