Skip to content

Commit

Permalink
feat!: upgrade to prettier v3 (#516)
Browse files Browse the repository at this point in the history
  • Loading branch information
JounQin authored Sep 2, 2022
1 parent 478b4e0 commit 44bbe5d
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 136 deletions.
5 changes: 5 additions & 0 deletions .changeset/orange-eyes-brush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"eslint-plugin-prettier": major
---

feat!: upgrade to prettier v3
8 changes: 8 additions & 0 deletions .changeset/pre.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"mode": "pre",
"tag": "alpha",
"initialVersions": {
"eslint-plugin-prettier": "4.2.2"
},
"changesets": []
}
158 changes: 30 additions & 128 deletions eslint-plugin-prettier.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
* @typedef {import('eslint').AST.Range} Range
* @typedef {import('eslint').AST.SourceLocation} SourceLocation
* @typedef {import('eslint').ESLint.Plugin} Plugin
* @typedef {import('prettier').FileInfoOptions} FileInfoOptions
* @typedef {import('prettier').Options & { onDiskFilepath: string, parserPath: string, usePrettierrc?: boolean }} Options
*/

'use strict';
Expand All @@ -34,9 +36,9 @@ const { INSERT, DELETE, REPLACE } = generateDifferences;

// Lazily-loaded Prettier.
/**
* @type {typeof import('prettier')}
* @type {(source: string, options: Options, fileInfoOptions: FileInfoOptions) => string}
*/
let prettier;
let prettierFormat;

// ------------------------------------------------------------------------------
// Rule Definition
Expand Down Expand Up @@ -123,7 +125,10 @@ const eslintPluginPrettier = {
create(context) {
const usePrettierrc =
!context.options[1] || context.options[1].usePrettierrc !== false;
const eslintFileInfoOptions =
/**
* @type {FileInfoOptions}
*/
const fileInfoOptions =
(context.options[1] && context.options[1].fileInfoOptions) || {};
const sourceCode = context.getSourceCode();
const filepath = context.getFilename();
Expand All @@ -136,136 +141,19 @@ const eslintPluginPrettier = {
const source = sourceCode.text;

return {
// eslint-disable-next-line sonarjs/cognitive-complexity
Program() {
if (!prettier) {
if (!prettierFormat) {
// Prettier is expensive to load, so only load it if needed.
prettier = require('prettier');
prettierFormat = require('synckit').createSyncFn(
require.resolve('./worker'),
);
}

/**
* @type {{}}
*/
const eslintPrettierOptions = context.options[0] || {};

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

const { ignored, inferredParser } = prettier.getFileInfo.sync(
onDiskFilepath,
{
resolveConfig: false,
withNodeModules: false,
ignorePath: '.prettierignore',
plugins: prettierRcOptions ? prettierRcOptions.plugins : null,
...eslintFileInfoOptions,
},
);

// Skip if file is ignored using a .prettierignore file
if (ignored) {
return;
}

const initialOptions = {};

// 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.
// 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.
//
// `parserBlocklist` should contain the list of prettier parser
// names for file types where:
// * Prettier supports parsing the file type
// * There is an ESLint processor that extracts JavaScript snippets
// from the file type.
if (filepath === onDiskFilepath) {
// The following list means the plugin process source into js content
// but with same filename, so we need to change the parser to `babel`
// by default.
// Related ESLint plugins are:
// 1. `eslint-plugin-graphql` (replacement: `@graphql-eslint/eslint-plugin`)
// 2. `eslint-plugin-html`
// 3. `eslint-plugin-markdown@1` (replacement: `eslint-plugin-markdown@2+`)
// 4. `eslint-plugin-svelte3` (replacement: `eslint-plugin-svelte@2+`)
const parserBlocklist = [null, 'markdown', 'html'];

let inferParserToBabel = parserBlocklist.includes(inferredParser);

switch (inferredParser) {
// it could be processed by `@graphql-eslint/eslint-plugin` or `eslint-plugin-graphql`
case 'graphql': {
if (
// for `eslint-plugin-graphql`, see https://github.com/apollographql/eslint-plugin-graphql/blob/master/src/index.js#L416
source.startsWith('ESLintPluginGraphQLFile`')
) {
inferParserToBabel = true;
}
break;
}
// it could be processed by `@ota-meshi/eslint-plugin-svelte`, `eslint-plugin-svelte` or `eslint-plugin-svelte3`
case 'svelte': {
// The `source` would be modified by `eslint-plugin-svelte3`
if (!context.parserPath.includes('svelte-eslint-parser')) {
// We do not support `eslint-plugin-svelte3`,
// the users should run `prettier` on `.svelte` files manually
return;
}
}
}

if (inferParserToBabel) {
initialOptions.parser = 'babel';
}
} else {
// Similar to https://github.com/prettier/stylelint-prettier/pull/22
// In all of the following cases ESLint extracts a part of a file to
// be formatted and there exists a prettier parser for the whole file.
// If you're interested in prettier you'll want a fully formatted file so
// you're about to run prettier over the whole file anyway.
// Therefore running prettier over just the style section is wasteful, so
// skip it.
const parserBlocklist = [
'babel',
'babylon',
'flow',
'typescript',
'vue',
'markdown',
'html',
'mdx',
'angular',
'svelte',
];
if (
parserBlocklist.includes(/** @type {string} */ (inferredParser))
) {
return;
}
}

const prettierOptions = {
...initialOptions,
...prettierRcOptions,
...eslintPrettierOptions,
filepath,
};

// prettier.format() may throw a SyntaxError if it cannot parse the
// source code it is given. Usually for JS files this isn't a
// problem as ESLint will report invalid syntax before trying to
Expand All @@ -279,7 +167,17 @@ const eslintPluginPrettier = {
*/
let prettierSource;
try {
prettierSource = prettier.format(source, prettierOptions);
prettierSource = prettierFormat(
source,
{
...eslintPrettierOptions,
filepath,
onDiskFilepath,
parserPath: context.parserPath,
usePrettierrc,
},
fileInfoOptions,
);
} catch (err) {
if (!(err instanceof SyntaxError)) {
throw err;
Expand Down Expand Up @@ -308,6 +206,10 @@ const eslintPluginPrettier = {
return;
}

if (prettierSource == null) {
return;
}

if (source !== prettierSource) {
const differences = generateDifferences(source, prettierSource);

Expand Down
6 changes: 2 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
"prettier"
],
"scripts": {
"build": "tsc -b",
"format": "yarn prettier '**/*.{js,json,md,yml}' --write && yarn lint --fix",
"lint": "eslint . --cache -f friendly --max-warnings 10",
"prepare": "simple-git-hooks && yarn-deduplicate --strategy fewer || exit 0",
Expand All @@ -38,7 +37,7 @@
"peerDependencies": {
"@types/eslint": ">=8.0.0",
"eslint": ">=8.0.0",
"prettier": ">=2.0.0"
"prettier": ">=3.0.0"
},
"peerDependenciesMeta": {
"@types/eslint": {
Expand All @@ -49,7 +48,6 @@
}
},
"dependencies": {
"eslint-plugin-prettier": "link:.",
"prettier-linter-helpers": "^1.0.0"
},
"devDependencies": {
Expand All @@ -76,6 +74,6 @@
},
"resolutions": {
"eslint-plugin-prettier": "link:.",
"prettier": "^2.0.0"
"prettier": "^3.0.0-alpha.0"
}
}
Loading

0 comments on commit 44bbe5d

Please sign in to comment.