@automattic/eslint-plugin-wpvip 0.5.6 → 0.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CONTRIBUTING.md CHANGED
@@ -1,22 +1,9 @@
1
- # Contributing to `eslint-config-wpvip`
1
+ # Contributing
2
2
 
3
3
  ## Getting Started
4
4
 
5
- Clone this repo and run `npm install`.
6
-
7
- The rules for this shared config are declared in [index.js](./index.js) and are automatically applied to the code in this repo.
5
+ This repo provides custom ESLint rules (in `./rules`) and configs (`./configs`). Generally speaking, any change is welcome for discussion, but keep in mind that these rules and configs are used across all of our projects, so they need to be practical and flexible.
8
6
 
9
7
  ## Automated Testing
10
8
 
11
- We're using jest to confirm that our configuration does what we think it will.
12
-
13
- When you modify the rules, please add cases to the following files:
14
-
15
- * `__fixtures__/**/allowed.js` -- Syntax that should be allowed according to the rule(s) affected by your proposed change
16
- * `__fixtures__/**/disallowed.js` -- Syntax that should *NOT* be allowed according to the rule(s) affected by your proposed change
17
-
18
- After changing the rules or the `disallowed` fixture, run the following to update the snapshot of jest errors found:
19
-
20
- `npm run update-snapshot`
21
-
22
- ...and commit the change to the snapshot file in your branch / PR.
9
+ This repo lints itself! Try to add code in `__fixtures__` that will produce errors, confirm that the errors are caught, then run `npm run jest:update-snapshot` to expect the errors.
package/README.md CHANGED
@@ -18,9 +18,7 @@ Create an `.eslintrc.js` file. **Note:** The `init` file allows you to avoid ins
18
18
  require( '@automattic/eslint-plugin-wpvip/init' );
19
19
 
20
20
  module.exports = {
21
- extends: [
22
- 'plugin:@automattic/wpvip/recommended',
23
- ],
21
+ extends: [ 'plugin:@automattic/wpvip/recommended' ],
24
22
  root: true,
25
23
  };
26
24
  ```
@@ -29,6 +27,24 @@ And that's it! It works automatically with most Babel and TypeScript projects. C
29
27
 
30
28
  You may also wish to define an `.eslintignore` file if there are files or paths that you do not want to lint.
31
29
 
30
+ Package scripts can be useful to run linting and formatting commands automatically. Here are some suggested scripts for your project's `package.json`—only copy the ones that are useful to you. The `cmd:` scripts help you compose commands without repeating verbose CLI arguments.
31
+
32
+ ```json
33
+ {
34
+ "scripts": {
35
+ "cmd:format": "prettier '**/*.(js|json|jsx|md|ts|tsx|yml|yaml)'",
36
+ "cmd:lint": "eslint --ext 'js,jsx,ts,tsx'",
37
+ "format": "npm run cmd:format -- --write",
38
+ "format:check": "npm run cmd:format -- --check",
39
+ "lint": "npm run cmd:lint .",
40
+ "lint:fix": "npm run cmd:lint . -- --fix",
41
+ "lint:ignore-warnings": "npm run cmd:lint . -- --quiet"
42
+ }
43
+ }
44
+ ```
45
+
46
+ **Note:** ESLint automatically ignores files listed in `.eslintignore` or you can target `.gitignore` using `--ignore-path`. Similarly, Prettier automatically ignores files listed in `.prettierignore` or you can target `.gitignore` using `--ignore-path`.
47
+
32
48
  ## Recommended config
33
49
 
34
50
  The "recommended" config includes rules for JavaScript, TypeScript, Jest, and React, including rules related to formatting and white space. It is intended to be strict! Opinionated defaults keep our codebases consistent and reduce the friction we experience when context-switching between projects.
@@ -41,9 +57,9 @@ module.exports = {
41
57
  'plugin:@automattic/wpvip/javascript',
42
58
  'plugin:@automattic/wpvip/typescript', // when "typescript" is installed
43
59
  'plugin:@automattic/wpvip/formatting',
44
- 'plugin:@automattic/wpvip/testing', // when "jest" is installed
45
- 'plugin:@automattic/wpvip/react', // when "react" is installed
46
- 'plugin:@automattic/wpvip/prettier', // when "prettier" is installed
60
+ 'plugin:@automattic/wpvip/testing', // when "jest" is installed
61
+ 'plugin:@automattic/wpvip/react', // when "react" is installed
62
+ 'plugin:@automattic/wpvip/prettier', // when "prettier" is installed
47
63
  ],
48
64
  };
49
65
  ```
@@ -66,16 +82,17 @@ This repo also provides a Prettier config, which you can use with the following
66
82
 
67
83
  For maximum benefit, see [Prettier's documentation on enabling format-on-save in your editor](https://prettier.io/docs/en/editors.html). This enables you to concentrate on coding while Prettier handles formatting.
68
84
 
85
+ ### Editorconfig
86
+
87
+ [Editorconfig](https://editorconfig.org/) provides additional formatting rules and works well with Prettier. Copy the [`.editorconfig` file](./.editorconfig) from this repo into your project.
88
+
69
89
  ## CLI
70
90
 
71
91
  The `cli` config allows certain behaviors that are usually against best practice but are useful in a codebase that produces a CLI tool:
72
92
 
73
93
  ```js
74
94
  module.exports = {
75
- extends: [
76
- 'plugin:@automattic/wpvip/recommended',
77
- 'plugin:@automattic/wpvip/cli',
78
- ],
95
+ extends: [ 'plugin:@automattic/wpvip/recommended', 'plugin:@automattic/wpvip/cli' ],
79
96
  };
80
97
  ```
81
98
 
@@ -93,10 +110,7 @@ JSDoc is considered optional, especially compared to better alternatives like Ty
93
110
 
94
111
  ```js
95
112
  module.exports = {
96
- extends: [
97
- 'plugin:@automattic/wpvip/recommended',
98
- 'plugin:@automattic/wpvip/jsdoc',
99
- ],
113
+ extends: [ 'plugin:@automattic/wpvip/recommended', 'plugin:@automattic/wpvip/jsdoc' ],
100
114
  };
101
115
  ```
102
116
 
package/package.json CHANGED
@@ -1,15 +1,20 @@
1
1
  {
2
2
  "name": "@automattic/eslint-plugin-wpvip",
3
- "version": "0.5.6",
3
+ "version": "0.5.8",
4
4
  "description": "ESLint plugin for internal WordPress VIP projects",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "check-types": "tsc __tests__/**/*.ts",
8
- "format": "prettier --ignore-path .gitignore --ignore-path .prettierignore --write '**/*.{js,ts}'",
9
- "jest": "npm run link-plugin && jest",
10
- "jest:update-snapshot": "jest --updateSnapshot",
8
+ "cmd:format": "prettier --ignore-path .gitignore '**/*.(js|json|jsx|md|ts|tsx|yml|yaml)'",
9
+ "cmd:jest": "npm run link-plugin && jest",
10
+ "cmd:lint": "npm run link-plugin && eslint --ext 'js,jsx,ts,tsx'",
11
+ "format": "npm run cmd:format -- --write",
12
+ "format:check": "npm run cmd:format -- --check",
13
+ "jest": "npm run cmd:jest",
14
+ "jest:update-snapshot": "npm run cmd:jest -- --updateSnapshot",
11
15
  "link-plugin": "mkdir -p ./node_modules/@automattic; ln -fns $(pwd) ./node_modules/@automattic/eslint-plugin-wpvip",
12
- "lint": "npm run link-plugin && eslint .",
16
+ "lint": "npm run cmd:lint .",
17
+ "lint:fix": "npm run cmd:lint . -- --fix",
13
18
  "test": "npm run jest"
14
19
  },
15
20
  "repository": {
package/prettierrc.js CHANGED
@@ -1,11 +1,18 @@
1
1
  module.exports = {
2
2
  arrowParens: 'avoid',
3
3
  bracketSpacing: true,
4
- jsxBracketSameLine: false,
5
4
  parenSpacing: true,
6
5
  printWidth: 100,
7
6
  semi: true,
8
7
  singleQuote: true,
9
8
  trailingComma: 'es5',
10
9
  useTabs: true,
10
+ overrides: [
11
+ {
12
+ files: [ '*.json', '*.yml', '*.yaml' ],
13
+ options: {
14
+ useTabs: false,
15
+ },
16
+ },
17
+ ],
11
18
  };
package/rules/README.md CHANGED
@@ -8,29 +8,29 @@ If you want to await a collection of tasks run in series (which is rarely the ca
8
8
 
9
9
  ```js
10
10
  async function* doTasks() {
11
- let i = 0;
12
- while (i < 10) {
13
- yield i++;
14
- }
11
+ let i = 0;
12
+ while ( i < 10 ) {
13
+ yield i++;
14
+ }
15
15
  }
16
16
 
17
- for await (const count of doTasks()) {
18
- console.log(count);
17
+ for await ( const count of doTasks() ) {
18
+ console.log( count );
19
19
  }
20
20
  ```
21
21
 
22
22
  ### The problem
23
23
 
24
- `Array.prototype.forEach` is not designed for async/await/promises. Even if the function passed to `.forEach` is `async`, each iteration does not `await` the result.
24
+ `Array.prototype.forEach` is not designed for async/await/promises. Even if the function passed to `.forEach` is `async`, each iteration does not `await` the result.
25
25
 
26
26
  ```js
27
- const letters = ['a', 'b', 'c'];
27
+ const letters = [ 'a', 'b', 'c' ];
28
28
 
29
- letters.forEach(async letter => {
30
- await processLetter(letter);
31
- });
29
+ letters.forEach( async letter => {
30
+ await processLetter( letter );
31
+ } );
32
32
 
33
- console.log('done! but not really');
33
+ console.log( 'done! but not really' );
34
34
  ```
35
35
 
36
36
  In the example above, `'done! but not really'` is logged before the promises returned by `processLetter` have resolved. This is because the array is iterated immediately and execution proceeds without awaiting promise resolution.
@@ -1,7 +1,23 @@
1
1
  const debugLog = require( './debug-log' );
2
2
  const findPackageJson = require( 'find-package-json' );
3
3
 
4
- const parent = findPackageJson( __dirname ).next()?.value || {};
4
+ // Get a list of all package.json files in the current directory tree, ascending
5
+ // up the tree from the current directory. Note that this code behaves differently
6
+ // when it is installed as a package vs. when we are linting the code in this repo.
7
+ //
8
+ // When installed as a package, the current directory is inside node_modules and is
9
+ // not the "package root" as we are thinking about it. In this case, we need to ignore
10
+ // all package.json files that are inside node_modules directories.
11
+ //
12
+ // When we are linting the code in this repo, the current directory is not inside
13
+ // node_modules and the first found "package.json" is the "package root."
14
+ //
15
+ // This problem is basically impossible to solve for all edge cases (like someone who
16
+ // runs `npm run lint` from inside "node_modules") but this code should work for
17
+ // most cases.
18
+ const packages = [ ...findPackageJson( __dirname ) ];
19
+ const parent =
20
+ packages.find( pkg => ! pkg.__path.includes( '/node_modules/' ) ) || packages.pop() || {};
5
21
 
6
22
  debugLog( `Found package.json: ${ parent.__path || 'none' }` );
7
23