Skip to content

feat: skip processing code blocks on specific languages like stylelint-prettier #415

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jun 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
!.eslintrc.js
test/fixtures
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ jobs:
node-version: [12, 14, 16]

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

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

Expand Down
61 changes: 46 additions & 15 deletions eslint-plugin-prettier.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,22 +179,53 @@ module.exports = {
// * Prettier supports parsing the file type
// * There is an ESLint processor that extracts JavaScript snippets
// from the file type.
const parserBlocklist = [null, 'markdown', 'html'];

let inferParserToBabel =
parserBlocklist.indexOf(inferredParser) !== -1;

if (
// it could be processed by `@graphql-eslint/eslint-plugin` or `eslint-plugin-graphql`
inferredParser === 'graphql' &&
// for `eslint-plugin-graphql`, see https://github.com/apollographql/eslint-plugin-graphql/blob/master/src/index.js#L416
source.startsWith('ESLintPluginGraphQLFile`')
) {
inferParserToBabel = true;
}
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-markdown@1` (replacement: `eslint-plugin-markdown@2+`)
// 3. `eslint-plugin-html`
const parserBlocklist = [null, 'markdown', 'html'];

let inferParserToBabel =
parserBlocklist.indexOf(inferredParser) !== -1;

if (
// it could be processed by `@graphql-eslint/eslint-plugin` or `eslint-plugin-graphql`
inferredParser === 'graphql' &&
// for `eslint-plugin-graphql`, see https://github.com/apollographql/eslint-plugin-graphql/blob/master/src/index.js#L416
source.startsWith('ESLintPluginGraphQLFile`')
) {
inferParserToBabel = true;
}

if (filepath === onDiskFilepath && inferParserToBabel) {
initialOptions.parser = 'babel';
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',
];
if (parserBlocklist.indexOf(inferredParser) !== -1) {
return;
}
}

const prettierOptions = Object.assign(
Expand Down
25 changes: 16 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,26 +35,33 @@
"prettier": ">=2.0.0"
},
"devDependencies": {
"@graphql-eslint/eslint-plugin": "^2.3.0",
"@graphql-eslint/eslint-plugin": "^2.5.0",
"@not-an-aardvark/node-release-script": "^0.1.0",
"eslint": "^8.1.0",
"@typescript-eslint/parser": "^5.29.0",
"eslint": "^8.18.0",
"eslint-config-not-an-aardvark": "^2.1.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-eslint-plugin": "^4.0.2",
"eslint-config-prettier": "^8.5.0",
"eslint-mdx": "^1.17.0",
"eslint-plugin-eslint-plugin": "^4.3.0",
"eslint-plugin-mdx": "^1.17.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "link:.",
"eslint-plugin-self": "^1.2.1",
"graphql": "^15.7.1",
"mocha": "^6.2.3",
"prettier": "^2.4.1",
"vue-eslint-parser": "^8.0.0"
"graphql": "^16.5.0",
"mocha": "^9.2.2",
"prettier": "^2.7.1",
"vue-eslint-parser": "^8.3.0"
},
"peerDependenciesMeta": {
"eslint-config-prettier": {
"optional": true
}
},
"resolutions": {
"@babel/traverse": "^7.18.5"
},
"engines": {
"node": ">=6.0.0"
"node": ">=12.0.0"
},
"license": "MIT"
}
7 changes: 7 additions & 0 deletions test/fixtures/mdx.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Fragment } from 'react'

<div>Hello World!</div>

```ts
export declare const x = 1
```
20 changes: 20 additions & 0 deletions test/invalid/mdx.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
CODE:
import React from 'react'

<div>Hello World</div>

OUTPUT:
import React from 'react';

<div>Hello World</div>

OPTIONS:
[]

ERRORS:
[
{
message: 'Insert `;`',
line: 1, column: 26, endLine: 1, endColumn: 26,
},
]
108 changes: 107 additions & 1 deletion test/prettier.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,38 @@ const path = require('path');
const eslintPluginPrettier = require('..');

const rule = eslintPluginPrettier.rules.prettier;
const RuleTester = require('eslint').RuleTester;

const assert = require('assert');
const { ESLint, RuleTester } = require('eslint');

// ------------------------------------------------------------------------------
// Tests
// ------------------------------------------------------------------------------

const eslint = new ESLint({
baseConfig: {
parserOptions: {
ecmaVersion: 2021,
ecmaFeatures: {
jsx: true,
},
sourceType: 'module',
},
extends: 'plugin:prettier/recommended',
overrides: [
{
files: '*.mdx',
extends: 'plugin:mdx/recommended',
settings: {
'mdx/code-block': true,
},
},
],
},
useEslintrc: false,
ignore: false,
});

const ruleTester = new RuleTester();

ruleTester.run('prettier', rule, {
Expand Down Expand Up @@ -154,6 +180,69 @@ eslintPluginGraphqlRuleTester.run('eslint-plugin-graphql', rule, {
invalid: [],
});

const mdxRuleTester = new RuleTester({
parser: require.resolve('eslint-mdx'),
parserOptions: {
...require('eslint-mdx').DEFAULT_PARSER_OPTIONS,
// mdx-js/eslint-mdx#366
ecmaVersion: 2021,
},
});

mdxRuleTester.run('eslint-plugin-mdx', rule, {
valid: [
{
code: [
"import React from 'react';",
'',
'<div>Hello World</div>',
'',
].join('\n'),
filename: 'valid.mdx',
},
],
invalid: [
Object.assign(loadInvalidFixture('mdx'), {
filename: 'invalid.mdx',
}),
],
});

runFixture('mdx', [
[
{
column: 33,
endColumn: 33,
endLine: 1,
fix: {
range: [32, 32],
text: ';',
},
line: 1,
message: 'Insert `;`',
messageId: 'insert',
nodeType: null,
ruleId: 'prettier/prettier',
severity: 2,
},
{
column: 27,
endColumn: 27,
endLine: 6,
fix: {
range: [91, 91],
text: ';',
},
line: 6,
message: 'Insert `;`',
messageId: 'insert',
nodeType: null,
ruleId: 'prettier/prettier',
severity: 2,
},
],
]);

// ------------------------------------------------------------------------------
// Helpers
// ------------------------------------------------------------------------------
Expand Down Expand Up @@ -193,3 +282,20 @@ function loadInvalidFixture(name) {
function getPrettierRcJsFilename(dir, file = 'dummy.js') {
return path.resolve(__dirname, `./prettierrc/${dir}/${file}`);
}

function runFixture(name, asserts) {
return eslint
.lintFiles(`test/fixtures/${name}.*`)
.then((results) =>
assert.deepStrictEqual(
asserts,
results.map(({ messages }) => messages)
)
)
.catch((err) => {
// eslint-disable-next-line no-console
console.error(err);
// eslint-disable-next-line no-process-exit
process.exit(1);
});
}
Loading