Skip to content

Commit

Permalink
fix: bump plugin peerDep
Browse files Browse the repository at this point in the history
And add test for this to never happen again

Fixes #1064

Co-authored-by: Rostislav Simonik <rostislav.simonik@technologystudio.sk>
  • Loading branch information
mightyiam and rostislav-simonik committed Mar 14, 2023
1 parent 67bf3a6 commit fb46a90
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 6 deletions.
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@
"TypeScript"
],
"dependencies": {
"@typescript-eslint/parser": "^5.0.0",
"@typescript-eslint/parser": "^5.43.0",
"eslint-config-standard": "17.0.0"
},
"peerDependencies": {
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/eslint-plugin": "^5.43.0",
"eslint": "^8.0.1",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-n": "^15.0.0",
Expand All @@ -75,7 +75,11 @@
"@types/node": "18.15.2",
"@types/npm-package-arg": "6.1.1",
"@types/semver": "7.3.13",
"@types/ungap__structured-clone": "0.3.0",
"@typescript-eslint_bottom/eslint-plugin": "npm:@typescript-eslint/eslint-plugin@5.43.0",
"@typescript-eslint_bottom/parser": "npm:@typescript-eslint/parser@5.43.0",
"@typescript-eslint/eslint-plugin": "5.50.0",
"@ungap/structured-clone": "1.0.2",
"ava": "5.2.0",
"editorconfig-checker": "5.0.1",
"eslint": "8.36.0",
Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ npm install --save-dev \
eslint-plugin-promise@^6.0.0 \
eslint-plugin-import@^2.25.2 \
eslint-plugin-n@^15.0.0 \
@typescript-eslint/eslint-plugin@^5.0.0 \
@typescript-eslint/eslint-plugin@^5.43.0 \
eslint-config-standard-with-typescript@latest
```

Expand Down
57 changes: 54 additions & 3 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import configStandard from './eslint-config-standard'
import { rules as typescriptEslintRules } from '@typescript-eslint/eslint-plugin'
import standardPkg from 'eslint-config-standard/package.json'
import type { NormalizedPackageJson, readPackageUp } from 'read-pkg-up'
import { Linter } from 'eslint'
import { Linter, ESLint } from 'eslint'
import { readFile } from 'fs/promises'
import { resolve } from 'path'
import npmPkgArg from 'npm-package-arg'
import semver from 'semver'
import inclusion from 'inclusion'
import { diff as justDiff } from 'just-diff'
import structuredClone from '@ungap/structured-clone'

interface PkgDetails {
pkgPath: string
Expand All @@ -34,6 +35,8 @@ const getPkgDetails = async (): Promise<PkgDetails> => {
return { pkgJson: ourPkg, pkgPath: readResult.path, ourDeps, ourPeerDeps, ourDevDeps }
}

const extractVersionSpec = (range: string): string => range.split('@').slice(-1)[0]

const equivalents = [...(new Linter()).getRules().keys()]
.filter(name => Object.prototype.hasOwnProperty.call(typescriptEslintRules, name))

Expand Down Expand Up @@ -297,6 +300,10 @@ const isPinnedRange = (rangeStr: string): boolean => {
range.set[0][0].operator === ''
}

const typescriptEslintBottom = '@typescript-eslint_bottom'
const typescriptEslintBottomPlugin = `${typescriptEslintBottom}/eslint-plugin`
const typescriptEslintBottomParser = `${typescriptEslintBottom}/parser`

test('Dependencies range types', async (t) => {
const { ourDeps, ourPeerDeps, ourDevDeps } = await getPkgDetails()

Expand All @@ -314,8 +321,9 @@ test('Dependencies range types', async (t) => {
)
}
}
for (const [name, range] of Object.entries(ourDevDeps)) {
t.true(isPinnedRange(range), `Dev dependency \`${name}: ${range}\` is pinned`)
for (const [name, spec] of Object.entries(ourDevDeps)) {
const range = name.startsWith(`${typescriptEslintBottom}/`) ? extractVersionSpec(spec) : spec
t.true(isPinnedRange(range), `Dev dependency \`${name}: ${spec}\` is pinned`)
}
})

Expand Down Expand Up @@ -495,3 +503,46 @@ test('all plugin rules are considered', (t) => {
})
t.deepEqual(inexplicablyExcludedRules, [], 'rules inexplicably excluded')
})

test('our configuration is compatible with the plugin and parser at bottom of peer dep range', async (t) => {
const { ourPeerDeps, ourDevDeps } = await getPkgDetails()

const peerDepRange = ourPeerDeps['@typescript-eslint/eslint-plugin']
if (peerDepRange === undefined) throw new Error()

const bottomPluginVersion = extractVersionSpec(ourDevDeps[typescriptEslintBottomPlugin])
const bottomParserVersion = extractVersionSpec(ourDevDeps[typescriptEslintBottomParser])

const minPeerDepVersion = semver.minVersion(peerDepRange)
if (minPeerDepVersion === null) throw new Error()

t.deepEqual(bottomPluginVersion, minPeerDepVersion.version, 'bottom plugin version is bottom of peer dep')
t.deepEqual(bottomParserVersion, minPeerDepVersion.version, 'bottom parser version is bottom of peer dep')

const config = structuredClone(exported)

config.parser = typescriptEslintBottomParser
config.plugins = [typescriptEslintBottomPlugin]

if (config.overrides === undefined) throw new Error()
const overrides = config.overrides[0]
if (overrides === undefined) throw new Error()

if (overrides.rules === undefined) throw new Error()

overrides.rules = Object.fromEntries(
Object.entries(overrides.rules).map(([name, config]) => [
name.replace('@typescript-eslint/', `${typescriptEslintBottom}/`),
config
])
)

const eslint = new ESLint({
useEslintrc: false,
overrideConfig: config
})

await t.notThrowsAsync(async () => {
await eslint.lintText('foo')
})
})

0 comments on commit fb46a90

Please sign in to comment.