eslint-plugin-prettier 3.3.0 → 4.0.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # Changelog
2
2
 
3
+ ## v4.0.0 (2021-08-30)
4
+
5
+ This breaking change drops support for old versions of ESLint, Prettier and
6
+ Node. You must use at least ESLint v7.28.0, Prettier v2.0.0 and Node v12.0.0.
7
+ Aside from that, usage of this plugin remains identical.
8
+
9
+ * v4 - Drop support for eslint 5/6, prettier 1, node 6/8 ([#429](git@github.com:prettier/eslint-plugin-prettier/issues/429)) ([acb56f3](git@github.com:prettier/eslint-plugin-prettier/commit/acb56f3b2891b2a6998a75a7d4406183d452ba16))
10
+
11
+ ## v3.4.1 (2021-08-20)
12
+
13
+ * build(deps): Bump glob-parent from 5.0.0 to 5.1.2 ([#420](git@github.com:prettier/eslint-plugin-prettier/issues/420)) ([b6d075c](git@github.com:prettier/eslint-plugin-prettier/commit/b6d075cf7111468e8af4161c306c7f37f09f220e))
14
+ * build(deps): Bump path-parse from 1.0.6 to 1.0.7 ([#425](git@github.com:prettier/eslint-plugin-prettier/issues/425)) ([24f957e](git@github.com:prettier/eslint-plugin-prettier/commit/24f957ee2a5476bb9cc8e64921b9841fc751391e))
15
+ * feat: support `@graphql-eslint/eslint-plugin` out of box ([#413](git@github.com:prettier/eslint-plugin-prettier/issues/413)) ([ec6fbb1](git@github.com:prettier/eslint-plugin-prettier/commit/ec6fbb159e2454c6e145db55480932dc953cf7c1))
16
+ * chore: add tests for Node 16 ([#410](git@github.com:prettier/eslint-plugin-prettier/issues/410)) ([76bd45e](git@github.com:prettier/eslint-plugin-prettier/commit/76bd45ece6d56eb52f75db6b4a1efdd2efb56392))
17
+
18
+ ## v3.4.0 (2021-04-15)
19
+
20
+ * feat: support processor virtual filename ([#401](git@github.com:prettier/eslint-plugin-prettier/issues/401)) ([ee0ccc6](git@github.com:prettier/eslint-plugin-prettier/commit/ee0ccc6ac06d13cd546e78b444e53164f59eb27f))
21
+ * Simplify report logic ([#380](git@github.com:prettier/eslint-plugin-prettier/issues/380)) ([d993f24](git@github.com:prettier/eslint-plugin-prettier/commit/d993f247b5661683af031ab3b93955a0dfe448fa))
22
+ * Update: README.md ([#375](git@github.com:prettier/eslint-plugin-prettier/issues/375)) ([3ea4242](git@github.com:prettier/eslint-plugin-prettier/commit/3ea4242a8d4acdb76eb7e7dca9e44d3e87db70e3))
23
+
24
+ ## v3.3.1 (2021-01-04)
25
+
26
+ * fix: add eslint-config-prettier as an optional peer dependency ([#374](git@github.com:prettier/eslint-plugin-prettier/issues/374)) ([d59df27](git@github.com:prettier/eslint-plugin-prettier/commit/d59df27890aaffec9e528ceb3155831a0261848d))
27
+ * build(deps-dev): bump eslint from 7.16.0 to 7.17.0 ([b87985d](git@github.com:prettier/eslint-plugin-prettier/commit/b87985d8b1986743374b56691bcc1633df8f4eae))
28
+ * build(deps-dev): bump eslint from 7.15.0 to 7.16.0 ([11e427e](git@github.com:prettier/eslint-plugin-prettier/commit/11e427e5d6cedeb26e3e03c8143be3496a24955a))
29
+
3
30
  ## v3.3.0 (2020-12-13)
4
31
 
5
32
  * Minor: Perf improvement: Do not clear the config cache on each run ([#368](git@github.com:prettier/eslint-plugin-prettier/issues/368)) ([1b90ea7](git@github.com:prettier/eslint-plugin-prettier/commit/1b90ea752636959babb27ebca5d67093c346dab9))
package/README.md CHANGED
@@ -4,6 +4,8 @@ Runs [Prettier](https://github.com/prettier/prettier) as an [ESLint](http://esli
4
4
 
5
5
  If your desired formatting does not match Prettier’s output, you should use a different tool such as [prettier-eslint](https://github.com/prettier/prettier-eslint) instead.
6
6
 
7
+ Please read [Integrating with linters](https://prettier.io/docs/en/integrating-with-linters.html) before installing.
8
+
7
9
  ## Sample
8
10
 
9
11
  ```js
@@ -74,20 +76,6 @@ This plugin ships with a `plugin:prettier/recommended` config that sets up both
74
76
 
75
77
  You can then set Prettier's own options inside a `.prettierrc` file.
76
78
 
77
- 3. Some ESLint plugins (such as [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react)) also contain rules that conflict with Prettier. Add extra exclusions for the plugins you use like so:
78
-
79
- ```json
80
- {
81
- "extends": [
82
- "plugin:prettier/recommended",
83
- "prettier/flowtype",
84
- "prettier/react"
85
- ]
86
- }
87
- ```
88
-
89
- For the list of every available exclusion rule set, please see the [readme of eslint-config-prettier](https://github.com/prettier/eslint-config-prettier/blob/master/README.md).
90
-
91
79
  Exactly what does `plugin:prettier/recommended` do? Well, this is what it expands to:
92
80
 
93
81
  ```json
@@ -102,7 +90,7 @@ Exactly what does `plugin:prettier/recommended` do? Well, this is what it expand
102
90
  }
103
91
  ```
104
92
 
105
- - `"extends": ["prettier"]` enables the main config from `eslint-config-prettier`, which turns off some ESLint core rules that conflict with Prettier.
93
+ - `"extends": ["prettier"]` enables the config from `eslint-config-prettier`, which turns off some ESLint rules that conflict with Prettier.
106
94
  - `"plugins": ["prettier"]` registers this plugin.
107
95
  - `"prettier/prettier": "error"` turns on the rule provided by this plugin, which runs Prettier from within ESLint.
108
96
  - `"arrow-body-style": "off"` and `"prefer-arrow-callback": "off"` turns off two ESLint core rules that unfortunately are problematic with this plugin – see the next section.
@@ -11,7 +11,7 @@
11
11
 
12
12
  const {
13
13
  showInvisibles,
14
- generateDifferences
14
+ generateDifferences,
15
15
  } = require('prettier-linter-helpers');
16
16
 
17
17
  // ------------------------------------------------------------------------------
@@ -25,6 +25,9 @@ const { INSERT, DELETE, REPLACE } = generateDifferences;
25
25
  // ------------------------------------------------------------------------------
26
26
 
27
27
  // Lazily-loaded Prettier.
28
+ /**
29
+ * @type {import('prettier')}
30
+ */
28
31
  let prettier;
29
32
 
30
33
  // ------------------------------------------------------------------------------
@@ -32,71 +35,26 @@ let prettier;
32
35
  // ------------------------------------------------------------------------------
33
36
 
34
37
  /**
35
- * Reports an "Insert ..." issue where text must be inserted.
36
- * @param {RuleContext} context - The ESLint rule context.
37
- * @param {number} offset - The source offset where to insert text.
38
- * @param {string} text - The text to be inserted.
39
- * @returns {void}
40
- */
41
- function reportInsert(context, offset, text) {
42
- const pos = context.getSourceCode().getLocFromIndex(offset);
43
- const range = [offset, offset];
44
- context.report({
45
- message: 'Insert `{{ code }}`',
46
- data: { code: showInvisibles(text) },
47
- loc: { start: pos, end: pos },
48
- fix(fixer) {
49
- return fixer.insertTextAfterRange(range, text);
50
- }
51
- });
52
- }
53
-
54
- /**
55
- * Reports a "Delete ..." issue where text must be deleted.
56
- * @param {RuleContext} context - The ESLint rule context.
57
- * @param {number} offset - The source offset where to delete text.
58
- * @param {string} text - The text to be deleted.
38
+ * Reports a difference.
39
+ * @param {import('eslint').Rule.RuleContext} context - The ESLint rule context.
40
+ * @param {import('prettier-linter-helpers').Difference} difference - The difference object.
59
41
  * @returns {void}
60
42
  */
61
- function reportDelete(context, offset, text) {
62
- const start = context.getSourceCode().getLocFromIndex(offset);
63
- const end = context.getSourceCode().getLocFromIndex(offset + text.length);
64
- const range = [offset, offset + text.length];
65
- context.report({
66
- message: 'Delete `{{ code }}`',
67
- data: { code: showInvisibles(text) },
68
- loc: { start, end },
69
- fix(fixer) {
70
- return fixer.removeRange(range);
71
- }
72
- });
73
- }
74
-
75
- /**
76
- * Reports a "Replace ... with ..." issue where text must be replaced.
77
- * @param {RuleContext} context - The ESLint rule context.
78
- * @param {number} offset - The source offset where to replace deleted text
79
- with inserted text.
80
- * @param {string} deleteText - The text to be deleted.
81
- * @param {string} insertText - The text to be inserted.
82
- * @returns {void}
83
- */
84
- function reportReplace(context, offset, deleteText, insertText) {
85
- const start = context.getSourceCode().getLocFromIndex(offset);
86
- const end = context
87
- .getSourceCode()
88
- .getLocFromIndex(offset + deleteText.length);
43
+ function reportDifference(context, difference) {
44
+ const { operation, offset, deleteText = '', insertText = '' } = difference;
89
45
  const range = [offset, offset + deleteText.length];
46
+ const [start, end] = range.map((index) =>
47
+ context.getSourceCode().getLocFromIndex(index)
48
+ );
49
+
90
50
  context.report({
91
- message: 'Replace `{{ deleteCode }}` with `{{ insertCode }}`',
51
+ messageId: operation,
92
52
  data: {
93
- deleteCode: showInvisibles(deleteText),
94
- insertCode: showInvisibles(insertText)
53
+ deleteText: showInvisibles(deleteText),
54
+ insertText: showInvisibles(insertText),
95
55
  },
96
56
  loc: { start, end },
97
- fix(fixer) {
98
- return fixer.replaceTextRange(range, insertText);
99
- }
57
+ fix: (fixer) => fixer.replaceTextRange(range, insertText),
100
58
  });
101
59
  }
102
60
 
@@ -112,15 +70,15 @@ module.exports = {
112
70
  rules: {
113
71
  'prettier/prettier': 'error',
114
72
  'arrow-body-style': 'off',
115
- 'prefer-arrow-callback': 'off'
116
- }
117
- }
73
+ 'prefer-arrow-callback': 'off',
74
+ },
75
+ },
118
76
  },
119
77
  rules: {
120
78
  prettier: {
121
79
  meta: {
122
80
  docs: {
123
- url: 'https://github.com/prettier/eslint-plugin-prettier#options'
81
+ url: 'https://github.com/prettier/eslint-plugin-prettier#options',
124
82
  },
125
83
  type: 'layout',
126
84
  fixable: 'code',
@@ -129,7 +87,7 @@ module.exports = {
129
87
  {
130
88
  type: 'object',
131
89
  properties: {},
132
- additionalProperties: true
90
+ additionalProperties: true,
133
91
  },
134
92
  {
135
93
  type: 'object',
@@ -138,12 +96,17 @@ module.exports = {
138
96
  fileInfoOptions: {
139
97
  type: 'object',
140
98
  properties: {},
141
- additionalProperties: true
142
- }
99
+ additionalProperties: true,
100
+ },
143
101
  },
144
- additionalProperties: true
145
- }
146
- ]
102
+ additionalProperties: true,
103
+ },
104
+ ],
105
+ messages: {
106
+ [INSERT]: 'Insert `{{ insertText }}`',
107
+ [DELETE]: 'Delete `{{ deleteText }}`',
108
+ [REPLACE]: 'Replace `{{ deleteText }}` with `{{ insertText }}`',
109
+ },
147
110
  },
148
111
  create(context) {
149
112
  const usePrettierrc =
@@ -152,6 +115,12 @@ module.exports = {
152
115
  (context.options[1] && context.options[1].fileInfoOptions) || {};
153
116
  const sourceCode = context.getSourceCode();
154
117
  const filepath = context.getFilename();
118
+ // Processors that extract content from a file, such as the markdown
119
+ // plugin extracting fenced code blocks may choose to specify virtual
120
+ // file paths. If this is the case then we need to resolve prettier
121
+ // config and file info using the on-disk path instead of the virtual
122
+ // path.
123
+ const onDiskFilepath = context.getPhysicalFilename();
155
124
  const source = sourceCode.text;
156
125
 
157
126
  return {
@@ -164,13 +133,13 @@ module.exports = {
164
133
  const eslintPrettierOptions = context.options[0] || {};
165
134
 
166
135
  const prettierRcOptions = usePrettierrc
167
- ? prettier.resolveConfig.sync(filepath, {
168
- editorconfig: true
136
+ ? prettier.resolveConfig.sync(onDiskFilepath, {
137
+ editorconfig: true,
169
138
  })
170
139
  : null;
171
140
 
172
- const prettierFileInfo = prettier.getFileInfo.sync(
173
- filepath,
141
+ const { ignored, inferredParser } = prettier.getFileInfo.sync(
142
+ onDiskFilepath,
174
143
  Object.assign(
175
144
  {},
176
145
  { resolveConfig: true, ignorePath: '.prettierignore' },
@@ -179,13 +148,13 @@ module.exports = {
179
148
  );
180
149
 
181
150
  // Skip if file is ignored using a .prettierignore file
182
- if (prettierFileInfo.ignored) {
151
+ if (ignored) {
183
152
  return;
184
153
  }
185
154
 
186
155
  const initialOptions = {};
187
156
 
188
- // ESLint suppports processors that let you extract and lint JS
157
+ // ESLint supports processors that let you extract and lint JS
189
158
  // fragments within a non-JS language. In the cases where prettier
190
159
  // supports the same language as a processor, we want to process
191
160
  // the provided source code as javascript (as ESLint provides the
@@ -193,9 +162,14 @@ module.exports = {
193
162
  // based off the filename. Otherwise, for instance, on a .md file we
194
163
  // end up trying to run prettier over a fragment of JS using the
195
164
  // markdown parser, which throws an error.
196
- // If we can't infer the parser from from the filename, either
197
- // because no filename was provided or because there is no parser
198
- // found for the filename, use javascript.
165
+ // Processors may set virtual filenames for these extracted blocks.
166
+ // If they do so then we want to trust the file extension they
167
+ // provide, and no override is needed.
168
+ // If the processor does not set any virtual filename (signified by
169
+ // `filepath` and `onDiskFilepath` being equal) AND we can't
170
+ // infer the parser from the filename, either because no filename
171
+ // was provided or because there is no parser found for the
172
+ // filename, use javascript.
199
173
  // This is added to the options first, so that
200
174
  // prettierRcOptions and eslintPrettierOptions can still override
201
175
  // the parser.
@@ -205,17 +179,22 @@ module.exports = {
205
179
  // * Prettier supports parsing the file type
206
180
  // * There is an ESLint processor that extracts JavaScript snippets
207
181
  // from the file type.
208
- const parserBlocklist = [null, 'graphql', 'markdown', 'html'];
182
+ const parserBlocklist = [null, 'markdown', 'html'];
183
+
184
+ let inferParserToBabel =
185
+ parserBlocklist.indexOf(inferredParser) !== -1;
186
+
209
187
  if (
210
- parserBlocklist.indexOf(prettierFileInfo.inferredParser) !== -1
188
+ // it could be processed by `@graphql-eslint/eslint-plugin` or `eslint-plugin-graphql`
189
+ inferredParser === 'graphql' &&
190
+ // for `eslint-plugin-graphql`, see https://github.com/apollographql/eslint-plugin-graphql/blob/master/src/index.js#L416
191
+ source.startsWith('ESLintPluginGraphQLFile`')
211
192
  ) {
212
- // Prettier v1.16.0 renamed the `babylon` parser to `babel`
213
- // Use the modern name if available
214
- const supportBabelParser = prettier
215
- .getSupportInfo()
216
- .languages.some(language => language.parsers.includes('babel'));
193
+ inferParserToBabel = true;
194
+ }
217
195
 
218
- initialOptions.parser = supportBabelParser ? 'babel' : 'babylon';
196
+ if (filepath === onDiskFilepath && inferParserToBabel) {
197
+ initialOptions.parser = 'babel';
219
198
  }
220
199
 
221
200
  const prettierOptions = Object.assign(
@@ -227,7 +206,7 @@ module.exports = {
227
206
  );
228
207
 
229
208
  // prettier.format() may throw a SyntaxError if it cannot parse the
230
- // source code it is given. Ususally for JS files this isn't a
209
+ // source code it is given. Usually for JS files this isn't a
231
210
  // problem as ESLint will report invalid syntax before trying to
232
211
  // pass it to the prettier plugin. However this might be a problem
233
212
  // for non-JS languages that are handled by a plugin. Notably Vue
@@ -245,7 +224,7 @@ module.exports = {
245
224
  let message = 'Parsing error: ' + err.message;
246
225
 
247
226
  // Prettier's message contains a codeframe style preview of the
248
- // invalid code and the line/column at which the error occured.
227
+ // invalid code and the line/column at which the error occurred.
249
228
  // ESLint shows those pieces of information elsewhere already so
250
229
  // remove them from the message
251
230
  if (err.codeFrame) {
@@ -263,36 +242,13 @@ module.exports = {
263
242
  if (source !== prettierSource) {
264
243
  const differences = generateDifferences(source, prettierSource);
265
244
 
266
- differences.forEach(difference => {
267
- switch (difference.operation) {
268
- case INSERT:
269
- reportInsert(
270
- context,
271
- difference.offset,
272
- difference.insertText
273
- );
274
- break;
275
- case DELETE:
276
- reportDelete(
277
- context,
278
- difference.offset,
279
- difference.deleteText
280
- );
281
- break;
282
- case REPLACE:
283
- reportReplace(
284
- context,
285
- difference.offset,
286
- difference.deleteText,
287
- difference.insertText
288
- );
289
- break;
290
- }
291
- });
245
+ for (const difference of differences) {
246
+ reportDifference(context, difference);
247
+ }
292
248
  }
293
- }
249
+ },
294
250
  };
295
- }
296
- }
297
- }
251
+ },
252
+ },
253
+ },
298
254
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-prettier",
3
- "version": "3.3.0",
3
+ "version": "4.0.0",
4
4
  "description": "Runs prettier as an eslint rule",
5
5
  "keywords": [
6
6
  "eslint",
@@ -31,23 +31,25 @@
31
31
  "prettier-linter-helpers": "^1.0.0"
32
32
  },
33
33
  "peerDependencies": {
34
- "eslint": ">=5.0.0",
35
- "prettier": ">=1.13.0"
34
+ "eslint": ">=7.28.0",
35
+ "prettier": ">=2.0.0"
36
36
  },
37
37
  "devDependencies": {
38
+ "@graphql-eslint/eslint-plugin": "^2.0.1",
38
39
  "@not-an-aardvark/node-release-script": "^0.1.0",
39
- "eslint": "^7.0.0",
40
+ "eslint": "^7.28.0",
40
41
  "eslint-config-not-an-aardvark": "^2.1.0",
41
42
  "eslint-config-prettier": "^6.0.0",
42
43
  "eslint-plugin-eslint-plugin": "^2.0.0",
43
44
  "eslint-plugin-node": "^8.0.0",
44
45
  "eslint-plugin-self": "^1.1.0",
46
+ "graphql": "^15.5.1",
45
47
  "mocha": "^6.0.0",
46
- "prettier": "^1.15.3",
48
+ "prettier": "^2.3.0",
47
49
  "vue-eslint-parser": "^6.0.0"
48
50
  },
49
51
  "peerDependenciesMeta": {
50
- "eslint-plugin-prettier": {
52
+ "eslint-config-prettier": {
51
53
  "optional": true
52
54
  }
53
55
  },