Skip to content

Commit 6fe4cbb

Browse files
committed
Add JSDoc based types & update unified
1 parent 883c7da commit 6fe4cbb

File tree

6 files changed

+139
-86
lines changed

6 files changed

+139
-86
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
coverage/
22
node_modules/
33
.DS_Store
4+
*.d.ts
45
*.log
56
yarn.lock

index.js

Lines changed: 80 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
import path from 'path'
2+
// @ts-expect-error: hush
23
import gitDiffTree from 'git-diff-tree'
34
import {findUpOne} from 'vfile-find-up'
45

56
const own = {}.hasOwnProperty
67

8+
/** @type {string} */
79
let previousRange
810

11+
/** @type {import('unified').Plugin<[]>} */
912
export default function diff() {
13+
/** @type {Record<string, string>} */
1014
let cache = {}
1115

12-
return transform
13-
14-
function transform(tree, file, next) {
16+
return function (_, file, next) {
1517
const base = file.dirname
18+
/** @type {string|undefined} */
1619
let commitRange
20+
/** @type {string[]|undefined} */
1721
let range
1822

1923
// Looks like Travis.
@@ -23,6 +27,7 @@ export default function diff() {
2327
}
2428
// Looks like GH Actions.
2529
else if (process.env.GITHUB_SHA) {
30+
// @ts-expect-error: fine.
2631
range =
2732
// This is a PR: check the whole PR.
2833
// Refs take the form `refs/heads/main`.
@@ -32,10 +37,17 @@ export default function diff() {
3237
process.env.GITHUB_HEAD_REF.split('/').pop()
3338
]
3439
: [process.env.GITHUB_SHA + '^1', process.env.GITHUB_SHA]
40+
// @ts-expect-error: We definitely just defined this
3541
commitRange = range.join('...')
3642
}
3743

38-
if (!base || !commitRange || range.length !== 2) {
44+
if (
45+
!base ||
46+
!commitRange ||
47+
!range ||
48+
!file.dirname ||
49+
range.length !== 2
50+
) {
3951
return next()
4052
}
4153

@@ -48,71 +60,84 @@ export default function diff() {
4860
if (own.call(cache, base)) {
4961
tick(cache[base])
5062
} else {
51-
findUpOne('.git', file.dirname, ongit)
52-
}
63+
findUpOne('.git', file.dirname, (error, git) => {
64+
// Never happens.
65+
/* c8 ignore next */
66+
if (error) return next(error)
5367

54-
function ongit(error, git) {
55-
// Never happens.
56-
/* c8 ignore next */
57-
if (error) return next(error)
68+
// Not testable in a Git repo…
69+
/* c8 ignore next */
70+
if (!git) return next(new Error('Not in a git repository'))
5871

59-
// Not testable in a Git repo…
60-
/* c8 ignore next */
61-
if (!git) return next(new Error('Not in a git repository'))
62-
63-
cache[base] = git.dirname
64-
tick(git.dirname)
72+
cache[base] = git.dirname
73+
tick(git.dirname)
74+
})
6575
}
6676

77+
/**
78+
* @param {string} root
79+
*/
6780
function tick(root) {
81+
/** @type {Record<string, [number, number][]>} */
6882
const diffs = {}
6983

7084
gitDiffTree(path.join(root, '.git'), {
85+
// @ts-expect-error: fine.
7186
originalRev: range[0],
87+
// @ts-expect-error: fine.
7288
rev: range[1]
7389
})
7490
.on('error', next)
75-
.on('data', (type, data) => {
76-
if (type !== 'patch') return
77-
78-
const lines = data.lines
79-
const re = /^@@ -(\d+),?(\d+)? \+(\d+),?(\d+)? @@/
80-
const match = lines[0].match(re)
81-
82-
// Should not happen, maybe if Git returns weird diffs?
83-
/* c8 ignore next */
84-
if (!match) return
85-
86-
const ranges = []
87-
const start = Number.parseInt(match[3], 10) - 1
88-
let index = 0
89-
let position
90-
91-
while (++index < lines.length) {
92-
const line = lines[index]
93-
94-
if (line.charAt(0) === '+') {
95-
const no = start + index
96-
97-
if (position === undefined) {
98-
position = ranges.length
99-
ranges.push([no, no])
91+
.on(
92+
'data',
93+
/**
94+
* @param {string} type
95+
* @param {{lines: string, aPath: string, bPath: string}} data
96+
*/
97+
(type, data) => {
98+
if (type !== 'patch') return
99+
100+
const lines = data.lines
101+
const re = /^@@ -(\d+),?(\d+)? \+(\d+),?(\d+)? @@/
102+
const match = lines[0].match(re)
103+
104+
// Should not happen, maybe if Git returns weird diffs?
105+
/* c8 ignore next */
106+
if (!match) return
107+
108+
/** @type {[number, number][]} */
109+
const ranges = []
110+
const start = Number.parseInt(match[3], 10) - 1
111+
let index = 0
112+
/** @type {number|undefined} */
113+
let position
114+
115+
while (++index < lines.length) {
116+
const line = lines[index]
117+
118+
if (line.charAt(0) === '+') {
119+
const no = start + index
120+
121+
if (position === undefined) {
122+
position = ranges.length
123+
ranges.push([no, no])
124+
} else {
125+
ranges[position][1] = no
126+
}
100127
} else {
101-
ranges[position][1] = no
128+
position = undefined
102129
}
103-
} else {
104-
position = undefined
105130
}
106-
}
107131

108-
const fp = path.resolve(root, data.bPath)
132+
const fp = path.resolve(root, data.bPath)
109133

110-
// Long diffs.
111-
/* c8 ignore next */
112-
if (!(fp in diffs)) diffs[fp] = []
134+
// Long diffs.
135+
/* c8 ignore next */
136+
if (!(fp in diffs)) diffs[fp] = []
113137

114-
diffs[fp].push(...ranges)
115-
})
138+
diffs[fp].push(...ranges)
139+
}
140+
)
116141
.on('end', () => {
117142
const fp = path.resolve(file.cwd, file.path)
118143
const ranges = diffs[fp]
@@ -125,7 +150,10 @@ export default function diff() {
125150

126151
file.messages = file.messages.filter((message) =>
127152
ranges.some(
128-
(range) => message.line >= range[0] && message.line <= range[1]
153+
(range) =>
154+
message.line &&
155+
message.line >= range[0] &&
156+
message.line <= range[1]
129157
)
130158
)
131159

package.json

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,32 +28,40 @@
2828
"sideEffects": false,
2929
"type": "module",
3030
"main": "index.js",
31+
"types": "index.d.ts",
3132
"files": [
33+
"index.d.ts",
3234
"index.js"
3335
],
3436
"dependencies": {
3537
"git-diff-tree": "^1.0.0",
3638
"vfile-find-up": "^6.0.0"
3739
},
3840
"devDependencies": {
41+
"@types/rimraf": "^3.0.0",
42+
"@types/tape": "^4.0.0",
3943
"c8": "^7.0.0",
4044
"nlcst-to-string": "^3.0.0",
4145
"prettier": "^2.0.0",
4246
"remark-cli": "^9.0.0",
4347
"remark-preset-wooorm": "^8.0.0",
4448
"retext-english": "^3.0.0",
4549
"retext-stringify": "^2.0.0",
50+
"rimraf": "^3.0.0",
4651
"tape": "^5.0.0",
4752
"to-vfile": "^7.0.0",
48-
"unified": "^10.0.0-beta.1",
53+
"type-coverage": "^2.0.0",
54+
"typescript": "^4.0.0",
55+
"unified": "^10.0.0",
4956
"unist-util-visit": "^3.0.0",
5057
"xo": "^0.39.0"
5158
},
5259
"scripts": {
60+
"build": "rimraf \"*.d.ts\" \"test/**/*.d.ts\" && tsc && type-coverage",
5361
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
5462
"test-api": "node --conditions development test/index.js",
5563
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node --conditions development test/index.js",
56-
"test": "npm run format && npm run test-coverage"
64+
"test": "npm run build && npm run format && npm run test-coverage"
5765
},
5866
"prettier": {
5967
"tabWidth": 2,
@@ -70,5 +78,11 @@
7078
"plugins": [
7179
"preset-wooorm"
7280
]
81+
},
82+
"typeCoverage": {
83+
"atLeast": 100,
84+
"detail": true,
85+
"strict": true,
86+
"ignoreCatch": true
7387
}
7488
}

test/index.js

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import cp from 'child_process'
2-
import {promises as fsPromises} from 'fs'
2+
import fs from 'fs'
33
import path from 'path'
44
import {promisify} from 'util'
55
import test from 'tape'
66
import {toVFile} from 'to-vfile'
77
import {processor} from './processor.js'
8+
import rimraf from 'rimraf'
89

910
const exec = promisify(cp.exec)
1011

@@ -23,6 +24,16 @@ const current = process.cwd()
2324

2425
process.chdir(path.join(current, 'test'))
2526

27+
process.on('exit', async () => {
28+
process.env.TRAVIS_COMMIT_RANGE = range
29+
process.env.GITHUB_SHA = sha
30+
process.env.GITHUB_BASE_REF = base
31+
process.env.GITHUB_HEAD_REF = head
32+
process.chdir(path.join(current))
33+
fs.rmSync(path.join('test', '.git'), {recursive: true, force: true})
34+
fs.rmSync(path.join('test', 'example.txt'))
35+
})
36+
2637
test('diff() (travis)', async (t) => {
2738
const stepOne = [
2839
'Lorem ipsum dolor sit amet.',
@@ -37,6 +48,7 @@ test('diff() (travis)', async (t) => {
3748
t.plan(7)
3849

3950
await exec('git init')
51+
4052
// Set up.
4153
try {
4254
await exec('git config --global user.email')
@@ -135,11 +147,9 @@ test('diff() (travis)', async (t) => {
135147
t.pass('should pass')
136148

137149
delete process.env.TRAVIS_COMMIT_RANGE
138-
await Promise.allSettled([
139-
fsPromises.rm('.git', {recursive: true, force: true}),
140-
fsPromises.rm('new.txt'),
141-
fsPromises.rm('example.txt')
142-
])
150+
rimraf.sync('.git')
151+
rimraf.sync('new.txt')
152+
rimraf.sync('example.txt')
143153
})
144154

145155
test('diff() (GitHub Actions)', async (t) => {
@@ -213,16 +223,6 @@ test('diff() (GitHub Actions)', async (t) => {
213223
delete process.env.GITHUB_SHA
214224
delete process.env.GITHUB_BASE_REF
215225
delete process.env.GITHUB_HEAD_REF
216-
await Promise.allSettled([
217-
fsPromises.rm('.git', {recursive: true, force: true}),
218-
fsPromises.rm('example.txt')
219-
])
220-
})
221-
222-
process.on('exit', () => {
223-
process.env.TRAVIS_COMMIT_RANGE = range
224-
process.env.GITHUB_SHA = sha
225-
process.env.GITHUB_BASE_REF = base
226-
process.env.GITHUB_HEAD_REF = head
227-
process.chdir(path.join(current))
226+
rimraf.sync('.git')
227+
rimraf.sync('example.txt')
228228
})

test/processor.js

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import {unified} from 'unified'
2+
// @ts-expect-error: next
23
import retextEnglish from 'retext-english'
4+
// @ts-expect-error: next
35
import retextStringify from 'retext-stringify'
46
import {visit} from 'unist-util-visit'
57
import {toString} from 'nlcst-to-string'
@@ -8,20 +10,12 @@ import unifiedDiff from '../index.js'
810
export const processor = unified()
911
.use(retextEnglish)
1012
.use(retextStringify)
11-
.use(lorem)
12-
.use(unifiedDiff)
13-
.freeze()
14-
15-
function lorem() {
16-
return transformer
17-
18-
function transformer(tree, file) {
19-
visit(tree, 'WordNode', visitor)
20-
21-
function visitor(node) {
13+
.use(() => (tree, file) => {
14+
visit(tree, 'WordNode', (node) => {
2215
if (/lorem/i.test(toString(node))) {
2316
file.message('No lorem!', node)
2417
}
25-
}
26-
}
27-
}
18+
})
19+
})
20+
.use(unifiedDiff)
21+
.freeze()

tsconfig.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"include": ["*.js", "test/**/*.js"],
3+
"compilerOptions": {
4+
"target": "ES2020",
5+
"lib": ["ES2020"],
6+
"module": "ES2020",
7+
"moduleResolution": "node",
8+
"allowJs": true,
9+
"checkJs": true,
10+
"declaration": true,
11+
"emitDeclarationOnly": true,
12+
"allowSyntheticDefaultImports": true,
13+
"skipLibCheck": true,
14+
"strict": true
15+
}
16+
}

0 commit comments

Comments
 (0)