Skip to content

Commit

Permalink
feat(plugin): add new eslint plugin with custom rules
Browse files Browse the repository at this point in the history
  • Loading branch information
dackmin committed Jun 12, 2020
1 parent 96a837b commit feba5cc
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 0 deletions.
45 changes: 45 additions & 0 deletions packages/eslint-plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Poool ESLint Plugin

> Custom set of ESLint rules we need and enforce at Poool
## Installation

```bash
yarn add eslint @poool/eslint-plugin --dev
```

## Usage

Load the plugin in your `.eslintrc.json` file:

```json
{
"plugins": ["@poool/eslint-plugin"]
}
```

Finally enable all the rules you would like to use (don't forget to disable to core rule!):

```json
{
"rules": {
"no-extra-parens": "off",
"@poool/no-extra-parens": "error"
}
}
```

## Shareable configurations

### Recommended

This plugin exports a recommended configuration that enforces some of our rules.

To enable this configuration use the `extends` property in your `.eslintrc.json`
config file:

```json
{
"extends": ["plugin:@poool/eslint-plugin/recommended"]
}
```
40 changes: 40 additions & 0 deletions packages/eslint-plugin/docs/rules/no-extra-parens.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Disallow extra parentheses (`@poool/no-extra-parens`)

Ensures there are no extra parentheses wrapping code.
Add a twist to the default `no-extra-parens` that allows conditional spreads to be wrapper around parentheses, for better clarity.

## Rule Details

The rule has exactly the same behavior as `no-extra-parens` except for conditional spreads.

#### Valid

```javascript
(() => {})();

() => ({ ...(true ? { foo: "bar" } : { bar: "foo" }) })

() => ({
...(true ? {
foo: 'bar',
} : { bar: 'foo' }),
})

const a = (1 + 1) * 2;
```

#### Invalid

```javascript
() => { return (true); }

() => ({ ...({ foo: "bar" }) })

() => ({
...((true) ? { // <- extra parentheses around true
foo: 'bar',
} : { bar: 'foo' }),
})

const a = (1 * 1) + 1;
```
17 changes: 17 additions & 0 deletions packages/eslint-plugin/lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const OFF = 0;
const ERROR = 2;

module.exports = {
rules: {
'no-extra-parens': require('./rules/no-extra-parens'),
},
configs: {
recommended: {
plugins: ['@poool/eslint-plugin'],
rules: {
'no-extra-parens': OFF,
'@poool/no-extra-parens': ERROR,
},
},
},
};
18 changes: 18 additions & 0 deletions packages/eslint-plugin/lib/rules/no-extra-parens.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const eslint = require('eslint');
const ruleComposer = require('eslint-rule-composer');

const rule = new eslint.Linter().getRules().get('no-extra-parens');

module.exports = ruleComposer.filterReports(
rule,
problem => {
if (
problem.node.type === 'ConditionalExpression' &&
problem.node.parent.type === 'SpreadElement'
) {
return false;
}

return problem;
},
);
29 changes: 29 additions & 0 deletions packages/eslint-plugin/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "@poool/eslint-plugin",
"version": "1.0.3",
"description": "Custom set of ESLint rules we need and enforce at Poool",
"main": "lib/index.js",
"repository": {
"type": "git",
"url": "https://github.com/p3ol/eslint-config.git",
"directory": "packages/eslint-plugin"
},
"author": "Ugo Stephant <ugo@poool.fr>",
"license": "MIT",
"peerDependencies": {
"eslint": "^6.8.0 || ^7.2.0"
},
"devDependencies": {
"eslint": "7.2.0",
"jest": "26.0.1"
},
"dependencies": {
"eslint-rule-composer": "0.3.0"
},
"publishConfig": {
"access": "public"
},
"scripts": {
"test": "./node_modules/.bin/jest"
}
}
48 changes: 48 additions & 0 deletions packages/eslint-plugin/tests/rules/no-extra-parens.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
const { RuleTester } = require('eslint');

const rule = require('../../lib/rules/no-extra-parens');

const runner = new RuleTester({ parserOptions: { ecmaVersion: 2020 } });

runner.run('no-extra-parens', rule, {
valid: [
'(() => {})()',
'() => ({ ...(true ? { foo: "bar" } : { bar: "foo" }) })',
`() => ({
...(true ? {
foo: 'bar',
} : { bar: 'foo' }),
})`,
'const a = (1 + 1) * 2;',
],
invalid: [
{
code: '() => { return (true); }',
errors: ['Unnecessary parentheses around expression.'],
output: '() => { return true; }',
},
{
code: '() => ({ ...({ foo: "bar" }) })',
errors: ['Unnecessary parentheses around expression.'],
output: '() => ({ ...{ foo: "bar" } })',
},
{
code: `() => ({
...((true) ? {
foo: 'bar',
} : { bar: 'foo' }),
})`,
errors: ['Unnecessary parentheses around expression.'],
output: `() => ({
...(true ? {
foo: 'bar',
} : { bar: 'foo' }),
})`,
},
{
code: 'const a = (1 * 1) + 1;',
errors: ['Unnecessary parentheses around expression.'],
output: 'const a = 1 * 1 + 1;',
},
],
});

0 comments on commit feba5cc

Please sign in to comment.