Skip to content
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

Drop supports Node.js v8-10, v13 and v15 #1588

Merged
merged 10 commits into from Oct 20, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
59 changes: 13 additions & 46 deletions .circleci/config.yml
Expand Up @@ -2,13 +2,12 @@ workflows:
version: 2
node-multi-build:
jobs:
- node-v8
- node-v10
- eslint-v6
- eslint-v7
- eslint-v8
- ts-eslint-v4
- node-v12
- node-v14
- node-v16
- lint

version: 2
Expand All @@ -35,9 +34,9 @@ jobs:
# paths:
# - node_modules

node-v8:
eslint-v6:
docker:
- image: node:8
- image: node:12
steps:
- run:
name: Versions
Expand All @@ -46,25 +45,7 @@ jobs:
- run:
name: Install eslint@6
command: |
npm install --save-exact eslint@6.8.0 @typescript-eslint/parser@3.10.1 typescript@4.0.8
- run:
name: Install dependencies
command: npm install
- run:
name: Test
command: npm test
node-v10:
docker:
- image: node:10
steps:
- run:
name: Versions
command: npm version
- checkout
- run:
name: Install eslint@7 and @typescript-eslint/parser@4
command: |
npm install eslint@7 @typescript-eslint/parser@^4
npm install --save-exact eslint@6.8.0
- run:
name: Install dependencies
command: npm install
Expand All @@ -73,7 +54,7 @@ jobs:
command: npm test
eslint-v7:
docker:
- image: node:10
- image: node:14
steps:
- run:
name: Versions
Expand All @@ -89,24 +70,6 @@ jobs:
- run:
name: Test
command: npm test
eslint-v8:
docker:
- image: node:14
steps:
- run:
name: Versions
command: npm version
- checkout
- run:
name: Install eslint@8
command: |
npm install eslint@^8.0.0-0
- run:
name: Install dependencies
command: npm install
- run:
name: Test
command: npm test
ts-eslint-v4:
docker:
- image: node:14
Expand All @@ -116,9 +79,9 @@ jobs:
command: npm version
- checkout
- run:
name: Install @typescript-eslint/parser@4
name: Install @typescript-eslint/parser@4 eslint@7
command: |
npm install @typescript-eslint/parser@^4
npm install @typescript-eslint/parser@^4 eslint@7
- run:
name: Install dependencies
command: npm install
Expand All @@ -133,6 +96,10 @@ jobs:
<<: *node-base
docker:
- image: node:14
node-v16:
<<: *node-base
docker:
- image: node:16

lint:
docker:
Expand All @@ -153,5 +120,5 @@ jobs:
paths:
- node_modules
- run:
name: Test
name: Lint
command: npm run lint
13 changes: 12 additions & 1 deletion .eslintrc.js
Expand Up @@ -10,7 +10,12 @@ module.exports = {
node: true,
mocha: true
},
extends: ['plugin:eslint-plugin/recommended', 'prettier'],
extends: [
'plugin:eslint-plugin/recommended',
'prettier',
'plugin:node-dependencies/recommended',
'plugin:jsonc/recommended-with-jsonc'
],
plugins: ['eslint-plugin', 'prettier'],
rules: {
'accessor-pairs': 2,
Expand Down Expand Up @@ -142,6 +147,12 @@ module.exports = {
'no-invalid-meta': 'error',
'no-invalid-meta-docs-categories': 'error'
}
},
{
files: ['*.json'],
rules: {
'prettier/prettier': 'off'
}
}
]
}
4 changes: 3 additions & 1 deletion .vscode/settings.json
Expand Up @@ -6,7 +6,9 @@
"eslint.validate": [
"javascript",
"javascriptreact",
"vue"
"vue",
"json",
"jsonc"
],
"typescript.tsdk": "node_modules/typescript/lib",
"vetur.validation.script": false,
Expand Down
2 changes: 1 addition & 1 deletion docs/user-guide/README.md
Expand Up @@ -23,7 +23,7 @@ yarn add -D eslint eslint-plugin-vue
::: tip Requirements

- ESLint v6.2.0 and above
- Node.js v8.10.0 and above
- Node.js v12.22.x, v14.17.x, v16.x and above

We have started supporting ESLint v8.0.0 beta, but note that beta support will be dropped once the stable version is released.

Expand Down
10 changes: 9 additions & 1 deletion eslint-internal-rules/.eslintrc.json
Expand Up @@ -2,5 +2,13 @@
"rules": {
"no-invalid-meta-docs-categories": "error",
"no-invalid-meta": "error"
}
},
"overrides": [
{
"files": ["*.json"],
"rules": {
"no-invalid-meta": "off"
}
}
]
}
207 changes: 1 addition & 206 deletions lib/rules/no-unsupported-features.js
Expand Up @@ -137,7 +137,7 @@ module.exports = {
* @returns {boolean} `true` if it's supporting.
*/
function isNotSupportingVersion(aCase) {
return !semverSubset(versionRange, getSemverRange(aCase.supported))
return !semver.subset(versionRange, getSemverRange(aCase.supported))
}

/** @type {TemplateListener} */
Expand Down Expand Up @@ -171,208 +171,3 @@ module.exports = {
)
}
}

// TODO replace semver.subset() in the major version.
/**
* semver.subset()
*
* We need to use a copy of the semver source code until a major version upgrade.
*
* @see https://github.com/npm/node-semver/blob/e79ac3a450e8bb504e78b8159e3efc70895699b8/ranges/subset.js#L43
* @license ISC at Isaac Z. Schlueter and Contributors
* https://github.com/npm/node-semver/blob/master/LICENSE
*
* @param {semver.Range} sub
* @param {semver.Range} dom
*/
function semverSubset(sub, dom) {
if (sub === dom) return true

sub = new semver.Range(sub)
dom = new semver.Range(dom)
let sawNonNull = false

// eslint-disable-next-line no-labels
OUTER: for (const simpleSub of sub.set) {
for (const simpleDom of dom.set) {
const isSub = simpleSubset(simpleSub, simpleDom)
sawNonNull = sawNonNull || isSub !== null
// eslint-disable-next-line no-labels
if (isSub) continue OUTER
}
if (sawNonNull) return false
}
return true
}

/**
* @license ISC at Isaac Z. Schlueter and Contributors
* https://github.com/npm/node-semver/blob/master/LICENSE
* @param {readonly semver.Comparator[]} sub
* @param {readonly semver.Comparator[]} dom
*/
function simpleSubset(sub, dom) {
if (sub === dom) return true

/**
* @param {semver.Comparator} c
*/
function isAny(c) {
return Object.keys(c.semver).length === 0
}

if (sub.length === 1 && isAny(sub[0])) {
if (dom.length === 1 && isAny(dom[0])) return true
else sub = [new semver.Comparator('>=0.0.0')]
}

if (dom.length === 1 && isAny(dom[0])) {
dom = [new semver.Comparator('>=0.0.0')]
}

const eqSet = new Set()
let gt, lt
for (const c of sub) {
if (c.operator === '>' || c.operator === '>=') gt = higherGT(gt, c)
else if (c.operator === '<' || c.operator === '<=') lt = lowerLT(lt, c)
else eqSet.add(c.semver)
}

if (eqSet.size > 1) return null

let gtltComp
if (gt && lt) {
gtltComp = semver.compare(gt.semver, lt.semver)
if (gtltComp > 0) return null
else if (gtltComp === 0 && (gt.operator !== '>=' || lt.operator !== '<='))
return null
}

// will iterate one or zero times
for (const eq of eqSet) {
if (gt && !semver.satisfies(eq, String(gt))) return null

if (lt && !semver.satisfies(eq, String(lt))) return null

for (const c of dom) {
if (!semver.satisfies(eq, String(c))) return false
}

return true
}

let higher, lower
let hasDomLT, hasDomGT
// if the subset has a prerelease, we need a comparator in the superset
// with the same tuple and a prerelease, or it's not a subset
let needDomLTPre = lt && lt.semver.prerelease.length ? lt.semver : false
let needDomGTPre = gt && gt.semver.prerelease.length ? gt.semver : false
// exception: <1.2.3-0 is the same as <1.2.3
if (
needDomLTPre &&
needDomLTPre.prerelease.length === 1 &&
lt &&
lt.operator === '<' &&
needDomLTPre.prerelease[0] === 0
) {
needDomLTPre = false
}

for (const c of dom) {
hasDomGT = hasDomGT || c.operator === '>' || c.operator === '>='
hasDomLT = hasDomLT || c.operator === '<' || c.operator === '<='
if (gt) {
if (needDomGTPre) {
if (
c.semver.prerelease &&
c.semver.prerelease.length &&
c.semver.major === needDomGTPre.major &&
c.semver.minor === needDomGTPre.minor &&
c.semver.patch === needDomGTPre.patch
) {
needDomGTPre = false
}
}
if (c.operator === '>' || c.operator === '>=') {
higher = higherGT(gt, c)
if (higher === c && higher !== gt) return false
} else if (
gt.operator === '>=' &&
!semver.satisfies(gt.semver, String(c))
)
return false
}
if (lt) {
if (needDomLTPre) {
if (
c.semver.prerelease &&
c.semver.prerelease.length &&
c.semver.major === needDomLTPre.major &&
c.semver.minor === needDomLTPre.minor &&
c.semver.patch === needDomLTPre.patch
) {
needDomLTPre = false
}
}
if (c.operator === '<' || c.operator === '<=') {
lower = lowerLT(lt, c)
if (lower === c && lower !== lt) return false
} else if (
lt.operator === '<=' &&
!semver.satisfies(lt.semver, String(c))
)
return false
}
if (!c.operator && (lt || gt) && gtltComp !== 0) return false
}

// if there was a < or >, and nothing in the dom, then must be false
// UNLESS it was limited by another range in the other direction.
// Eg, >1.0.0 <1.0.1 is still a subset of <2.0.0
if (gt && hasDomLT && !lt && gtltComp !== 0) return false

if (lt && hasDomGT && !gt && gtltComp !== 0) return false

// we needed a prerelease range in a specific tuple, but didn't get one
// then this isn't a subset. eg >=1.2.3-pre is not a subset of >=1.0.0,
// because it includes prereleases in the 1.2.3 tuple
if (needDomGTPre || needDomLTPre) return false

return true
}

/**
* @license ISC at Isaac Z. Schlueter and Contributors
* https://github.com/npm/node-semver/blob/master/LICENSE
* @param {semver.Comparator | void} a
* @param {semver.Comparator} b
*/
const higherGT = (a, b) => {
if (!a) return b
const comp = semver.compare(a.semver, b.semver)
return comp > 0
? a
: comp < 0
? b
: b.operator === '>' && a.operator === '>='
? b
: a
}

/**
* @license ISC at Isaac Z. Schlueter and Contributors
* https://github.com/npm/node-semver/blob/master/LICENSE
* @param {semver.Comparator | void} a
* @param {semver.Comparator} b
*/
const lowerLT = (a, b) => {
if (!a) return b
const comp = semver.compare(a.semver, b.semver)
return comp < 0
? a
: comp > 0
? b
: b.operator === '<' && a.operator === '<='
? b
: a
}