Skip to content

Commit acb56f3

Browse files
authoredAug 30, 2021
v4 - Drop support for eslint 5/6, prettier 1, node 6/8 (#429)
* Update required versions of eslint and prettier Now requires node 12, eslint >7.28.0 and prettier > 2.0.0 - prettier v2 changed some defaults, so tests needed to be slightly tweaked - dropping support for old eslint/node means we remove them from CI test matrixes and always run the graphql plugin tests * Enable trailing commas in prettier * Rework graphql test - No need to check if the depenency is installed anymore - Move it into its own ruletester - Add invalid test * Remove check that is unneeded now we only support prettier v2 * Use getPhysicalFilename
1 parent 402a0b8 commit acb56f3

File tree

12 files changed

+1087
-187
lines changed

12 files changed

+1087
-187
lines changed
 

‎.editorconfig

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# editorconfig.org
2+
root = true
3+
4+
[*]
5+
charset = utf-8
6+
end_of_line = lf
7+
indent_size = 2
8+
indent_style = space
9+
insert_final_newline = true
10+
trim_trailing_whitespace = true
11+
12+
# Markdown syntax specifies that trailing whitespaces can be meaningful,
13+
# so let’s not trim those. e.g. 2 trailing spaces = linebreak (<br />)
14+
# See https://daringfireball.net/projects/markdown/syntax#p
15+
[*.md]
16+
trim_trailing_whitespace = false
17+
18+
# Disable trailing whitespace removal in diff files,
19+
# where whitespace is meaningful
20+
[*.diff]
21+
trim_trailing_whitespace = false

‎.eslintrc.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ module.exports = {
66
'not-an-aardvark/node',
77
'plugin:node/recommended',
88
'plugin:eslint-plugin/recommended',
9-
'prettier'
9+
'prettier',
1010
],
1111
env: { mocha: true },
1212
root: true,
1313
rules: {
1414
'self/prettier': ['error'],
15-
'eslint-plugin/report-message-format': ['error', '^[^a-z].*\\.$']
16-
}
15+
'eslint-plugin/report-message-format': ['error', '^[^a-z].*\\.$'],
16+
},
1717
};

‎.github/workflows/ci.yml

+2-26
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,8 @@ jobs:
1111
runs-on: ubuntu-latest
1212
strategy:
1313
matrix:
14-
eslint-version: [7.x, 6.x, 5.x]
15-
node-version: [16.x, 14.x, 12.x, 10.x, 8.x, 6.x]
16-
test-graphql: [true, false]
17-
18-
exclude:
19-
# eslint 7 does not support node 6 or 8
20-
- eslint-version: 7.x
21-
node-version: 8.x
22-
- eslint-version: 7.x
23-
node-version: 6.x
24-
# eslint 6 does not support node 6
25-
# the version of chalk used in eslint 6 does not support node 8
26-
- eslint-version: 6.x
27-
node-version: 8.x
28-
- eslint-version: 6.x
29-
node-version: 6.x
30-
# @graphql-eslint/eslint-plugin does not support node 6 or 8 or 10
31-
- test-graphql: true
32-
node-version: 10.x
33-
- test-graphql: true
34-
node-version: 8.x
35-
- test-graphql: true
36-
node-version: 6.x
14+
eslint-version: [7.x]
15+
node-version: [16.x, 14.x, 12.x]
3716

3817
steps:
3918
- uses: actions/checkout@v2
@@ -49,8 +28,5 @@ jobs:
4928
- name: Install
5029
run: yarn install
5130

52-
- if: matrix.test-graphql == true
53-
run: yarn add -D @graphql-eslint/eslint-plugin graphql
54-
5531
- name: Test
5632
run: yarn run test

‎eslint-plugin-prettier.js

+22-55
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,9 @@
99
// Requirements
1010
// ------------------------------------------------------------------------------
1111

12-
const fs = require('fs');
13-
const path = require('path');
14-
1512
const {
1613
showInvisibles,
17-
generateDifferences
14+
generateDifferences,
1815
} = require('prettier-linter-helpers');
1916

2017
// ------------------------------------------------------------------------------
@@ -46,43 +43,21 @@ let prettier;
4643
function reportDifference(context, difference) {
4744
const { operation, offset, deleteText = '', insertText = '' } = difference;
4845
const range = [offset, offset + deleteText.length];
49-
const [start, end] = range.map(index =>
46+
const [start, end] = range.map((index) =>
5047
context.getSourceCode().getLocFromIndex(index)
5148
);
5249

5350
context.report({
5451
messageId: operation,
5552
data: {
5653
deleteText: showInvisibles(deleteText),
57-
insertText: showInvisibles(insertText)
54+
insertText: showInvisibles(insertText),
5855
},
5956
loc: { start, end },
60-
fix: fixer => fixer.replaceTextRange(range, insertText)
57+
fix: (fixer) => fixer.replaceTextRange(range, insertText),
6158
});
6259
}
6360

64-
/**
65-
* Given a filepath, get the nearest path that is a regular file.
66-
* The filepath provided by eslint may be a virtual filepath rather than a file
67-
* on disk. This attempts to transform a virtual path into an on-disk path
68-
* @param {string} filepath
69-
* @returns {string}
70-
*/
71-
function getOnDiskFilepath(filepath) {
72-
try {
73-
if (fs.statSync(filepath).isFile()) {
74-
return filepath;
75-
}
76-
} catch (err) {
77-
// https://github.com/eslint/eslint/issues/11989
78-
if (err.code === 'ENOTDIR') {
79-
return getOnDiskFilepath(path.dirname(filepath));
80-
}
81-
}
82-
83-
return filepath;
84-
}
85-
8661
// ------------------------------------------------------------------------------
8762
// Module Definition
8863
// ------------------------------------------------------------------------------
@@ -95,15 +70,15 @@ module.exports = {
9570
rules: {
9671
'prettier/prettier': 'error',
9772
'arrow-body-style': 'off',
98-
'prefer-arrow-callback': 'off'
99-
}
100-
}
73+
'prefer-arrow-callback': 'off',
74+
},
75+
},
10176
},
10277
rules: {
10378
prettier: {
10479
meta: {
10580
docs: {
106-
url: 'https://github.com/prettier/eslint-plugin-prettier#options'
81+
url: 'https://github.com/prettier/eslint-plugin-prettier#options',
10782
},
10883
type: 'layout',
10984
fixable: 'code',
@@ -112,7 +87,7 @@ module.exports = {
11287
{
11388
type: 'object',
11489
properties: {},
115-
additionalProperties: true
90+
additionalProperties: true,
11691
},
11792
{
11893
type: 'object',
@@ -121,17 +96,17 @@ module.exports = {
12196
fileInfoOptions: {
12297
type: 'object',
12398
properties: {},
124-
additionalProperties: true
125-
}
99+
additionalProperties: true,
100+
},
126101
},
127-
additionalProperties: true
128-
}
102+
additionalProperties: true,
103+
},
129104
],
130105
messages: {
131106
[INSERT]: 'Insert `{{ insertText }}`',
132107
[DELETE]: 'Delete `{{ deleteText }}`',
133-
[REPLACE]: 'Replace `{{ deleteText }}` with `{{ insertText }}`'
134-
}
108+
[REPLACE]: 'Replace `{{ deleteText }}` with `{{ insertText }}`',
109+
},
135110
},
136111
create(context) {
137112
const usePrettierrc =
@@ -145,9 +120,7 @@ module.exports = {
145120
// file paths. If this is the case then we need to resolve prettier
146121
// config and file info using the on-disk path instead of the virtual
147122
// path.
148-
// See https://github.com/eslint/eslint/issues/11989 for ideas around
149-
// being able to get this value directly from eslint in the future.
150-
const onDiskFilepath = getOnDiskFilepath(filepath);
123+
const onDiskFilepath = context.getPhysicalFilename();
151124
const source = sourceCode.text;
152125

153126
return {
@@ -161,7 +134,7 @@ module.exports = {
161134

162135
const prettierRcOptions = usePrettierrc
163136
? prettier.resolveConfig.sync(onDiskFilepath, {
164-
editorconfig: true
137+
editorconfig: true,
165138
})
166139
: null;
167140

@@ -221,13 +194,7 @@ module.exports = {
221194
}
222195

223196
if (filepath === onDiskFilepath && inferParserToBabel) {
224-
// Prettier v1.16.0 renamed the `babylon` parser to `babel`
225-
// Use the modern name if available
226-
const supportBabelParser = prettier
227-
.getSupportInfo()
228-
.languages.some(language => language.parsers.includes('babel'));
229-
230-
initialOptions.parser = supportBabelParser ? 'babel' : 'babylon';
197+
initialOptions.parser = 'babel';
231198
}
232199

233200
const prettierOptions = Object.assign(
@@ -279,9 +246,9 @@ module.exports = {
279246
reportDifference(context, difference);
280247
}
281248
}
282-
}
249+
},
283250
};
284-
}
285-
}
286-
}
251+
},
252+
},
253+
},
287254
};

‎package.json

+6-4
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,21 @@
3131
"prettier-linter-helpers": "^1.0.0"
3232
},
3333
"peerDependencies": {
34-
"eslint": ">=5.0.0",
35-
"prettier": ">=1.13.0"
34+
"eslint": ">=7.28.0",
35+
"prettier": ">=2.0.0"
3636
},
3737
"devDependencies": {
38+
"@graphql-eslint/eslint-plugin": "^2.0.1",
3839
"@not-an-aardvark/node-release-script": "^0.1.0",
39-
"eslint": "^7.0.0",
40+
"eslint": "^7.28.0",
4041
"eslint-config-not-an-aardvark": "^2.1.0",
4142
"eslint-config-prettier": "^6.0.0",
4243
"eslint-plugin-eslint-plugin": "^2.0.0",
4344
"eslint-plugin-node": "^8.0.0",
4445
"eslint-plugin-self": "^1.1.0",
46+
"graphql": "^15.5.1",
4547
"mocha": "^6.0.0",
46-
"prettier": "^1.15.3",
48+
"prettier": "^2.3.0",
4749
"vue-eslint-parser": "^6.0.0"
4850
},
4951
"peerDependenciesMeta": {

‎test/invalid/10.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
CODE:
22
var a = {
3-
b: 1
3+
b: 1,
44
};
55

66
OUTPUT:
77
var a = {
8-
b: 1
8+
b: 1,
99
};
1010

1111
OPTIONS:

‎test/invalid/11-a.txt

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ var a = {
55

66
OUTPUT:
77
var a = {
8-
b: ""
8+
b: "",
99
};
1010

1111
OPTIONS:
@@ -14,7 +14,7 @@ OPTIONS:
1414
ERRORS:
1515
[
1616
{
17-
message: 'Replace `\'\',` with `""`',
18-
line: 2, column: 6, endLine: 2, endColumn: 9,
17+
message: 'Replace `\'\'` with `""`',
18+
line: 2, column: 6, endLine: 2, endColumn: 8,
1919
},
2020
]

‎test/invalid/11-b.txt

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ var a = {
55

66
OUTPUT:
77
var a = {
8-
b: ""
8+
b: "",
99
};
1010

1111
OPTIONS:
@@ -14,7 +14,7 @@ OPTIONS:
1414
ERRORS:
1515
[
1616
{
17-
message: 'Replace `\'\',` with `""`',
18-
line: 2, column: 6, endLine: 2, endColumn: 9,
17+
message: 'Replace `\'\'` with `""`',
18+
line: 2, column: 6, endLine: 2, endColumn: 8,
1919
},
2020
]

‎test/invalid/graphql.txt

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
CODE:
2+
type Query {
3+
foo: String!
4+
}
5+
6+
OUTPUT:
7+
type Query {
8+
foo: String!
9+
}
10+
11+
OPTIONS:
12+
[]
13+
14+
ERRORS:
15+
[
16+
{
17+
message: 'Insert `··`',
18+
line: 2, column: 1, endLine: 2, endColumn: 1,
19+
},
20+
]

‎test/prettier.js

+62-57
Original file line numberDiff line numberDiff line change
@@ -26,85 +26,48 @@ const RuleTester = require('eslint').RuleTester;
2626

2727
const ruleTester = new RuleTester();
2828

29-
let graphqlEslintParserPath;
30-
31-
try {
32-
graphqlEslintParserPath = require.resolve('@graphql-eslint/eslint-plugin');
33-
} catch (e) {
34-
// ignore
35-
}
36-
3729
ruleTester.run('prettier', rule, {
3830
valid: [
39-
// Correct style.
31+
// Correct style. Also proves that the plugin works if no filename is provided
4032
{ code: `'';\n` },
4133
// Double quote from .prettierrc.
4234
{ code: '"";\n', filename: getPrettierRcJsFilename('double-quote') },
4335
// Override .prettierrc from object option.
4436
{
4537
code: `var foo = {bar: 0};\n`,
4638
filename: getPrettierRcJsFilename('bracket-spacing'),
47-
options: [{ bracketSpacing: false }]
39+
options: [{ bracketSpacing: false }],
4840
},
4941
// Only use options from plugin, skipping .prettierrc
5042
{
5143
code: `var foo = {bar: 0};\n`,
5244
filename: getPrettierRcJsFilename('bracket-spacing'),
53-
options: [{ bracketSpacing: false }, { usePrettierrc: false }]
45+
options: [{ bracketSpacing: false }, { usePrettierrc: false }],
5446
},
5547
// Ignores filenames in .prettierignore
5648
{
5749
code: `("");\n`,
58-
filename: getPrettierRcJsFilename('single-quote', 'ignore-me.js')
50+
filename: getPrettierRcJsFilename('single-quote', 'ignore-me.js'),
5951
},
6052
// Sets a default parser when it can't be inferred from the file extensions
6153
{
6254
code: `('');\n`,
63-
filename: getPrettierRcJsFilename('single-quote', 'dummy.qqq')
55+
filename: getPrettierRcJsFilename('single-quote', 'dummy.qqq'),
6456
},
6557
// Overwrites the parser for file extensions prettier would try to format
6658
// with not the babylon parser
6759
// In the real world, eslint-plugin-markdown would transform file contents
6860
// into JS snippets that would get passed to ESLint
6961
{
7062
code: `('');\n`,
71-
filename: getPrettierRcJsFilename('single-quote', 'dummy.md')
63+
filename: getPrettierRcJsFilename('single-quote', 'dummy.md'),
7264
},
7365
// Should ignore files from node_modules
7466
{
7567
code: 'a();;;;;;\n',
76-
filename: 'node_modules/dummy.js'
68+
filename: 'node_modules/dummy.js',
7769
},
78-
// ESLint processors can provide virtual filenames. E.g. fenced code blocks
79-
// in a markdown file may be processed with the filenames
80-
// `a-markdown-file.md/1.js` / `a-markdown-file.md/2.js`
81-
// If we try and pass those filenames into prettier's `resolveConfig` and
82-
// `getFileInfo` methods they throw up because the it doesn't like treating
83-
// `markdown-file.md` as a directory.
84-
// Make sure we handle that case internally so this does not crash
85-
{
86-
code: `('');\n`,
87-
filename: path.join(__filename, '0_fake_virtual_name.js')
88-
},
89-
{
90-
code: 'ESLintPluginGraphQLFile`type Query {\n foo: String!\n}`\n',
91-
filename: getPrettierRcJsFilename('no-semi', 'dummy.graphql'),
92-
parserOptions: {
93-
ecmaVersion: 2015
94-
}
95-
}
96-
].concat(
97-
graphqlEslintParserPath
98-
? {
99-
code: `type Query {
100-
foo: String!
101-
}
102-
`,
103-
filename: 'valid.graphql',
104-
parser: graphqlEslintParserPath
105-
}
106-
: []
107-
),
70+
],
10871
invalid: [
10972
'01',
11073
'02',
@@ -124,29 +87,71 @@ ruleTester.run('prettier', rule, {
12487
'15',
12588
'16',
12689
'17',
127-
'18'
128-
].map(loadInvalidFixture)
90+
'18',
91+
].map(loadInvalidFixture),
12992
});
13093

13194
const vueRuleTester = new RuleTester({
132-
parser: require.resolve('vue-eslint-parser')
95+
parser: require.resolve('vue-eslint-parser'),
13396
});
13497

135-
vueRuleTester.run('prettier', rule, {
98+
vueRuleTester.run('vue', rule, {
13699
valid: [
137100
{
138101
code: `<template>\n <div>HI</div>\n</template>\n<script>\n3;\n</script>\n`,
139-
filename: 'valid.vue'
140-
}
102+
filename: 'valid.vue',
103+
},
141104
],
142105
invalid: [
143106
Object.assign(loadInvalidFixture('vue'), {
144-
filename: 'invalid.vue'
107+
filename: 'invalid.vue',
145108
}),
146109
Object.assign(loadInvalidFixture('vue-syntax-error'), {
147-
filename: 'syntax-error.vue'
148-
})
149-
]
110+
filename: 'syntax-error.vue',
111+
}),
112+
],
113+
});
114+
115+
const atGraphqlEslintRuleTester = new RuleTester({
116+
parser: require.resolve('@graphql-eslint/eslint-plugin'),
117+
});
118+
119+
atGraphqlEslintRuleTester.run('@graphql-eslint/eslint-plugin', rule, {
120+
valid: [
121+
{
122+
code: `type Query {\n foo: String!\n}\n`,
123+
filename: 'valid.graphql',
124+
},
125+
],
126+
invalid: [
127+
Object.assign(loadInvalidFixture('graphql'), {
128+
filename: 'invalid.graphql',
129+
}),
130+
],
131+
});
132+
133+
// eslint-plugin-graphql handles literal graphql files by tranforming graphql
134+
// code with a processor, instead of using a parser. Unfortunatly we cant
135+
// specify custom processors in a RuleTester, so instead we have write test code
136+
// that is the result of eslint-plugin-graphql's processing - this is the
137+
// ESLintPluginGraphQLFile tagged template literal. See
138+
// https://github.com/apollographql/eslint-plugin-graphql/blob/c465fedc8fea239ee1731ad4ec3ee1183a3cdddf/src/index.js#L404
139+
// In the future if ESLint supports processors (https://github.com/eslint/rfcs/pull/31)
140+
// we should be define a RuleTester like
141+
// `newRuleTester({processor: require('eslint-plugin-graphql').processor['.graphql']})
142+
// and then pass in pure graphql into the code value.
143+
const eslintPluginGraphqlRuleTester = new RuleTester({
144+
parserOptions: { ecmaVersion: 2015 },
145+
});
146+
147+
eslintPluginGraphqlRuleTester.run('eslint-plugin-graphql', rule, {
148+
valid: [
149+
{
150+
code: 'ESLintPluginGraphQLFile`type Query {\n foo: String!\n}`\n',
151+
filename: getPrettierRcJsFilename('no-semi', 'dummy.graphql'),
152+
},
153+
],
154+
invalid: [],
150155
});
151156

152157
// ------------------------------------------------------------------------------
@@ -166,13 +171,13 @@ function loadInvalidFixture(name) {
166171
const src = fs.readFileSync(filename, 'utf8');
167172
const sections = src
168173
.split(/^[A-Z]+:\n/m)
169-
.map(x => x.replace(/(?=\n)\n$/, ''));
174+
.map((x) => x.replace(/(?=\n)\n$/, ''));
170175
const item = {
171176
code: sections[1],
172177
output: sections[2],
173178
options: eval(sections[3]), // eslint-disable-line no-eval
174179
errors: eval(sections[4]), // eslint-disable-line no-eval
175-
filename: getPrettierRcJsFilename('double-quote', name + '.txt')
180+
filename: getPrettierRcJsFilename('double-quote', name + '.txt'),
176181
};
177182
if (sections.length >= 6) {
178183
item.filename = sections[5];

‎test/prettierrc/no-semi/.prettierrc

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
{
22
"semi": false
33
}
4-

‎yarn.lock

+943-33
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.