Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: prettier/eslint-plugin-prettier
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v3.3.1
Choose a base ref
...
head repository: prettier/eslint-plugin-prettier
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0813a83512ab52194b4e8da7193daf880a8cbef5
Choose a head ref
  • 17 commits
  • 9 files changed
  • 9 contributors

Commits on Jan 18, 2021

  1. build(deps-dev): bump eslint from 7.17.0 to 7.18.0

    Bumps [eslint](https://github.com/eslint/eslint) from 7.17.0 to 7.18.0.
    - [Release notes](https://github.com/eslint/eslint/releases)
    - [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
    - [Commits](eslint/eslint@v7.17.0...v7.18.0)
    
    Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
    dependabot-preview[bot] committed Jan 18, 2021

    Unverified

    This user has not yet uploaded their public signing key.
    Copy the full SHA
    13c19a6 View commit details
  2. Update: README.md (#375)

    Suggest new users read `Integrating with linters`
    christiantakle authored Jan 18, 2021

    Unverified

    This user has not yet uploaded their public signing key.
    Copy the full SHA
    3ea4242 View commit details

Commits on Jan 31, 2021

  1. Simplify report logic (#380)

    fisker authored Jan 31, 2021
    Copy the full SHA
    d993f24 View commit details

Commits on Feb 1, 2021

  1. build(deps-dev): bump eslint from 7.18.0 to 7.19.0

    Bumps [eslint](https://github.com/eslint/eslint) from 7.18.0 to 7.19.0.
    - [Release notes](https://github.com/eslint/eslint/releases)
    - [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
    - [Commits](eslint/eslint@v7.18.0...v7.19.0)
    
    Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
    dependabot-preview[bot] committed Feb 1, 2021
    Copy the full SHA
    ec80591 View commit details

Commits on Feb 15, 2021

  1. build(deps-dev): bump eslint from 7.19.0 to 7.20.0

    Bumps [eslint](https://github.com/eslint/eslint) from 7.19.0 to 7.20.0.
    - [Release notes](https://github.com/eslint/eslint/releases)
    - [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
    - [Commits](eslint/eslint@v7.19.0...v7.20.0)
    
    Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
    dependabot-preview[bot] committed Feb 15, 2021
    Copy the full SHA
    875eca4 View commit details

Commits on Feb 21, 2021

  1. Copy the full SHA
    7d5d3dd View commit details

Commits on Mar 1, 2021

  1. build(deps-dev): bump eslint from 7.20.0 to 7.21.0

    Bumps [eslint](https://github.com/eslint/eslint) from 7.20.0 to 7.21.0.
    - [Release notes](https://github.com/eslint/eslint/releases)
    - [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
    - [Commits](eslint/eslint@v7.20.0...v7.21.0)
    
    Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
    dependabot-preview[bot] committed Mar 1, 2021
    Copy the full SHA
    1f20666 View commit details

Commits on Mar 15, 2021

  1. build(deps-dev): bump eslint from 7.21.0 to 7.22.0

    Bumps [eslint](https://github.com/eslint/eslint) from 7.21.0 to 7.22.0.
    - [Release notes](https://github.com/eslint/eslint/releases)
    - [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
    - [Commits](eslint/eslint@v7.21.0...v7.22.0)
    
    Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
    dependabot-preview[bot] committed Mar 15, 2021
    Copy the full SHA
    2303314 View commit details

Commits on Mar 29, 2021

  1. build(deps-dev): bump eslint from 7.22.0 to 7.23.0

    Bumps [eslint](https://github.com/eslint/eslint) from 7.22.0 to 7.23.0.
    - [Release notes](https://github.com/eslint/eslint/releases)
    - [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
    - [Commits](eslint/eslint@v7.22.0...v7.23.0)
    
    Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
    dependabot-preview[bot] committed Mar 29, 2021
    Copy the full SHA
    959ab36 View commit details
  2. build(deps): [security] bump y18n from 4.0.0 to 4.0.1

    Bumps [y18n](https://github.com/yargs/y18n) from 4.0.0 to 4.0.1. **This update includes a security fix.**
    - [Release notes](https://github.com/yargs/y18n/releases)
    - [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md)
    - [Commits](https://github.com/yargs/y18n/commits)
    
    Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
    dependabot-preview[bot] committed Mar 29, 2021
    Copy the full SHA
    1f531b2 View commit details

Commits on Apr 12, 2021

  1. build(deps-dev): bump eslint from 7.23.0 to 7.24.0

    Bumps [eslint](https://github.com/eslint/eslint) from 7.23.0 to 7.24.0.
    - [Release notes](https://github.com/eslint/eslint/releases)
    - [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
    - [Commits](eslint/eslint@v7.23.0...v7.24.0)
    
    Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
    dependabot-preview[bot] committed Apr 12, 2021
    Copy the full SHA
    e4b06ad View commit details

Commits on Apr 14, 2021

  1. Copy the full SHA
    d1a5b2b View commit details
  2. feat: support processor virtual filename (#401)

    * feat: support processor virtual filename
    
    close #393
    
    * refactor: normalize filepath first in case recursive virtual filename
    JounQin authored Apr 14, 2021
    Copy the full SHA
    ee0ccc6 View commit details

Commits on Apr 15, 2021

  1. Copy the full SHA
    2ee9363 View commit details
  2. build(deps): bump actions/setup-node from v1 to v2.1.5 (#409)

    * build(deps): bump actions/setup-node from v1 to v2.1.5
    
    Bumps [actions/setup-node](https://github.com/actions/setup-node) from v1 to v2.1.5.
    - [Release notes](https://github.com/actions/setup-node/releases)
    - [Commits](actions/setup-node@v1...46071b5)
    
    Signed-off-by: dependabot[bot] <support@github.com>
    
    * Update .github/workflows/ci.yml
    
    Co-authored-by: Michaël De Boey <info@michaeldeboey.be>
    
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    Co-authored-by: Ben Scott <227292+BPScott@users.noreply.github.com>
    Co-authored-by: Michaël De Boey <info@michaeldeboey.be>
    3 people authored Apr 15, 2021
    Copy the full SHA
    f7e603b View commit details
  3. Dependabot ignores

    BPScott committed Apr 15, 2021
    Copy the full SHA
    81288b4 View commit details
  4. Copy the full SHA
    0813a83 View commit details
Showing with 166 additions and 149 deletions.
  1. +20 −0 .github/dependabot.yml
  2. +1 −1 .github/workflows/ci.yml
  3. +6 −0 CHANGELOG.md
  4. +3 −15 README.md
  5. +0 −6 dependabot.yml
  6. +69 −90 eslint-plugin-prettier.js
  7. +1 −1 package.json
  8. +11 −0 test/prettier.js
  9. +55 −36 yarn.lock
20 changes: 20 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
version: 2
updates:
- package-ecosystem: npm
directory: /
schedule:
interval: monthly
ignore:
# We're deliberatly targeting heavy backwards compatability to avoid
# making a breaking change and causing churn for the sake of it.
# Ignore dependencies that would result in or requre a breaking change
- dependency-name: 'eslint'
- dependency-name: 'eslint-*'
- dependency-name: 'prettier'
- dependency-name: 'vue-eslint-parser'
- dependency-name: 'mocha'

- package-ecosystem: github-actions
directory: /
schedule:
interval: monthly
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ jobs:
- uses: actions/checkout@v2

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}

6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## v3.4.0 (2021-04-15)

* 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))
* Simplify report logic ([#380](git@github.com:prettier/eslint-plugin-prettier/issues/380)) ([d993f24](git@github.com:prettier/eslint-plugin-prettier/commit/d993f247b5661683af031ab3b93955a0dfe448fa))
* Update: README.md ([#375](git@github.com:prettier/eslint-plugin-prettier/issues/375)) ([3ea4242](git@github.com:prettier/eslint-plugin-prettier/commit/3ea4242a8d4acdb76eb7e7dca9e44d3e87db70e3))

## v3.3.1 (2021-01-04)

* 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))
18 changes: 3 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -4,6 +4,8 @@ Runs [Prettier](https://github.com/prettier/prettier) as an [ESLint](http://esli

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.

Please read [Integrating with linters](https://prettier.io/docs/en/integrating-with-linters.html) before installing.

## Sample

```js
@@ -74,20 +76,6 @@ This plugin ships with a `plugin:prettier/recommended` config that sets up both

You can then set Prettier's own options inside a `.prettierrc` file.

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:

```json
{
"extends": [
"plugin:prettier/recommended",
"prettier/flowtype",
"prettier/react"
]
}
```

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

Exactly what does `plugin:prettier/recommended` do? Well, this is what it expands to:

```json
@@ -102,7 +90,7 @@ Exactly what does `plugin:prettier/recommended` do? Well, this is what it expand
}
```

- `"extends": ["prettier"]` enables the main config from `eslint-config-prettier`, which turns off some ESLint core rules that conflict with Prettier.
- `"extends": ["prettier"]` enables the config from `eslint-config-prettier`, which turns off some ESLint rules that conflict with Prettier.
- `"plugins": ["prettier"]` registers this plugin.
- `"prettier/prettier": "error"` turns on the rule provided by this plugin, which runs Prettier from within ESLint.
- `"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.
6 changes: 0 additions & 6 deletions dependabot.yml

This file was deleted.

159 changes: 69 additions & 90 deletions eslint-plugin-prettier.js
Original file line number Diff line number Diff line change
@@ -9,6 +9,9 @@
// Requirements
// ------------------------------------------------------------------------------

const fs = require('fs');
const path = require('path');

const {
showInvisibles,
generateDifferences
@@ -25,79 +28,59 @@ const { INSERT, DELETE, REPLACE } = generateDifferences;
// ------------------------------------------------------------------------------

// Lazily-loaded Prettier.
/**
* @type {import('prettier')}
*/
let prettier;

// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------

/**
* Reports an "Insert ..." issue where text must be inserted.
* @param {RuleContext} context - The ESLint rule context.
* @param {number} offset - The source offset where to insert text.
* @param {string} text - The text to be inserted.
* Reports a difference.
* @param {import('eslint').Rule.RuleContext} context - The ESLint rule context.
* @param {import('prettier-linter-helpers').Difference} difference - The difference object.
* @returns {void}
*/
function reportInsert(context, offset, text) {
const pos = context.getSourceCode().getLocFromIndex(offset);
const range = [offset, offset];
context.report({
message: 'Insert `{{ code }}`',
data: { code: showInvisibles(text) },
loc: { start: pos, end: pos },
fix(fixer) {
return fixer.insertTextAfterRange(range, text);
}
});
}
function reportDifference(context, difference) {
const { operation, offset, deleteText = '', insertText = '' } = difference;
const range = [offset, offset + deleteText.length];
const [start, end] = range.map(index =>
context.getSourceCode().getLocFromIndex(index)
);

/**
* Reports a "Delete ..." issue where text must be deleted.
* @param {RuleContext} context - The ESLint rule context.
* @param {number} offset - The source offset where to delete text.
* @param {string} text - The text to be deleted.
* @returns {void}
*/
function reportDelete(context, offset, text) {
const start = context.getSourceCode().getLocFromIndex(offset);
const end = context.getSourceCode().getLocFromIndex(offset + text.length);
const range = [offset, offset + text.length];
context.report({
message: 'Delete `{{ code }}`',
data: { code: showInvisibles(text) },
messageId: operation,
data: {
deleteText: showInvisibles(deleteText),
insertText: showInvisibles(insertText)
},
loc: { start, end },
fix(fixer) {
return fixer.removeRange(range);
}
fix: fixer => fixer.replaceTextRange(range, insertText)
});
}

/**
* Reports a "Replace ... with ..." issue where text must be replaced.
* @param {RuleContext} context - The ESLint rule context.
* @param {number} offset - The source offset where to replace deleted text
with inserted text.
* @param {string} deleteText - The text to be deleted.
* @param {string} insertText - The text to be inserted.
* @returns {void}
* Given a filepath, get the nearest path that is a regular file.
* The filepath provided by eslint may be a virtual filepath rather than a file
* on disk. This attempts to transform a virtual path into an on-disk path
* @param {string} filepath
* @returns {string}
*/
function reportReplace(context, offset, deleteText, insertText) {
const start = context.getSourceCode().getLocFromIndex(offset);
const end = context
.getSourceCode()
.getLocFromIndex(offset + deleteText.length);
const range = [offset, offset + deleteText.length];
context.report({
message: 'Replace `{{ deleteCode }}` with `{{ insertCode }}`',
data: {
deleteCode: showInvisibles(deleteText),
insertCode: showInvisibles(insertText)
},
loc: { start, end },
fix(fixer) {
return fixer.replaceTextRange(range, insertText);
function getOnDiskFilepath(filepath) {
try {
if (fs.statSync(filepath).isFile()) {
return filepath;
}
});
} catch (err) {
// https://github.com/eslint/eslint/issues/11989
if (err.code === 'ENOTDIR') {
return getOnDiskFilepath(path.dirname(filepath));
}
}

return filepath;
}

// ------------------------------------------------------------------------------
@@ -143,7 +126,12 @@ module.exports = {
},
additionalProperties: true
}
]
],
messages: {
[INSERT]: 'Insert `{{ insertText }}`',
[DELETE]: 'Delete `{{ deleteText }}`',
[REPLACE]: 'Replace `{{ deleteText }}` with `{{ insertText }}`'
}
},
create(context) {
const usePrettierrc =
@@ -152,6 +140,14 @@ module.exports = {
(context.options[1] && context.options[1].fileInfoOptions) || {};
const sourceCode = context.getSourceCode();
const filepath = context.getFilename();
// Processors that extract content from a file, such as the markdown
// plugin extracting fenced code blocks may choose to specify virtual
// file paths. If this is the case then we need to resolve prettier
// config and file info using the on-disk path instead of the virtual
// path.
// See https://github.com/eslint/eslint/issues/11989 for ideas around
// being able to get this value directly from eslint in the future.
const onDiskFilepath = getOnDiskFilepath(filepath);
const source = sourceCode.text;

return {
@@ -164,13 +160,13 @@ module.exports = {
const eslintPrettierOptions = context.options[0] || {};

const prettierRcOptions = usePrettierrc
? prettier.resolveConfig.sync(filepath, {
? prettier.resolveConfig.sync(onDiskFilepath, {
editorconfig: true
})
: null;

const prettierFileInfo = prettier.getFileInfo.sync(
filepath,
onDiskFilepath,
Object.assign(
{},
{ resolveConfig: true, ignorePath: '.prettierignore' },
@@ -185,17 +181,22 @@ module.exports = {

const initialOptions = {};

// ESLint suppports processors that let you extract and lint JS
// ESLint supports processors that let you extract and lint JS
// fragments within a non-JS language. In the cases where prettier
// supports the same language as a processor, we want to process
// the provided source code as javascript (as ESLint provides the
// rules with fragments of JS) instead of guessing the parser
// based off the filename. Otherwise, for instance, on a .md file we
// end up trying to run prettier over a fragment of JS using the
// markdown parser, which throws an error.
// If we can't infer the parser from from the filename, either
// because no filename was provided or because there is no parser
// found for the filename, use javascript.
// Processors may set virtual filenames for these extracted blocks.
// If they do so then we want to trust the file extension they
// provide, and no override is needed.
// If the processor does not set any virtual filename (signified by
// `filepath` and `onDiskFilepath` being equal) AND we can't
// infer the parser from the filename, either because no filename
// was provided or because there is no parser found for the
// filename, use javascript.
// This is added to the options first, so that
// prettierRcOptions and eslintPrettierOptions can still override
// the parser.
@@ -207,6 +208,7 @@ module.exports = {
// from the file type.
const parserBlocklist = [null, 'graphql', 'markdown', 'html'];
if (
filepath === onDiskFilepath &&
parserBlocklist.indexOf(prettierFileInfo.inferredParser) !== -1
) {
// Prettier v1.16.0 renamed the `babylon` parser to `babel`
@@ -227,7 +229,7 @@ module.exports = {
);

// prettier.format() may throw a SyntaxError if it cannot parse the
// source code it is given. Ususally for JS files this isn't a
// source code it is given. Usually for JS files this isn't a
// problem as ESLint will report invalid syntax before trying to
// pass it to the prettier plugin. However this might be a problem
// for non-JS languages that are handled by a plugin. Notably Vue
@@ -245,7 +247,7 @@ module.exports = {
let message = 'Parsing error: ' + err.message;

// Prettier's message contains a codeframe style preview of the
// invalid code and the line/column at which the error occured.
// invalid code and the line/column at which the error occurred.
// ESLint shows those pieces of information elsewhere already so
// remove them from the message
if (err.codeFrame) {
@@ -263,32 +265,9 @@ module.exports = {
if (source !== prettierSource) {
const differences = generateDifferences(source, prettierSource);

differences.forEach(difference => {
switch (difference.operation) {
case INSERT:
reportInsert(
context,
difference.offset,
difference.insertText
);
break;
case DELETE:
reportDelete(
context,
difference.offset,
difference.deleteText
);
break;
case REPLACE:
reportReplace(
context,
difference.offset,
difference.deleteText,
difference.insertText
);
break;
}
});
for (const difference of differences) {
reportDifference(context, difference);
}
}
}
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eslint-plugin-prettier",
"version": "3.3.1",
"version": "3.4.0",
"description": "Runs prettier as an eslint rule",
"keywords": [
"eslint",
11 changes: 11 additions & 0 deletions test/prettier.js
Original file line number Diff line number Diff line change
@@ -66,6 +66,17 @@ ruleTester.run('prettier', rule, {
{
code: 'a();;;;;;\n',
filename: 'node_modules/dummy.js'
},
// ESLint processors can provide virtual filenames. E.g. fenced code blocks
// in a markdown file may be processed with the filenames
// `a-markdown-file.md/1.js` / `a-markdown-file.md/2.js`
// If we try and pass those filenames into prettier's `resolveConfig` and
// `getFileInfo` methods they throw up because the it doesn't like treating
// `markdown-file.md` as a directory.
// Make sure we handle that case internally so this does not crash
{
code: `('');\n`,
filename: path.join(__filename, '0_fake_virtual_name.js')
}
],
invalid: [
Loading