refactor: use promise event APIs for git log processing

Iterate the log parser with for-await instead of data/end/error
callbacks (spawn errors are forwarded by destroying the stream), and
await the single-file lookup with events.once, which rejects on
child error by itself.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pull/5342/head
Divyansh Singh 1 month ago
parent 388577c6da
commit f97605ff26

@ -1,4 +1,5 @@
import { spawn, sync } from 'cross-spawn' import { spawn, sync } from 'cross-spawn'
import { once } from 'node:events'
import fs from 'node:fs' import fs from 'node:fs'
import path from 'node:path' import path from 'node:path'
import { Transform, type TransformCallback } from 'node:stream' import { Transform, type TransformCallback } from 'node:stream'
@ -120,23 +121,17 @@ export async function cacheAllGitTimestamps(
...pathspec ...pathspec
] ]
return new Promise((resolve, reject) => {
cache.clear() cache.clear()
const child = spawn('git', args, { cwd: root }) const child = spawn('git', args, { cwd: root })
const records = child.stdout.pipe(new GitLogParser())
child.on('error', (err) => records.destroy(err))
child.stdout for await (const rec of records as AsyncIterable<GitLogRecord>) {
.pipe(new GitLogParser())
.on('data', (rec: GitLogRecord) => {
for (const file of rec.files) { for (const file of rec.files) {
const slashed = slash(path.resolve(gitRoot, file)) const slashed = slash(path.resolve(gitRoot, file))
if (!cache.has(slashed)) cache.set(slashed, rec.ts) if (!cache.has(slashed)) cache.set(slashed, rec.ts)
} }
}) }
.on('error', reject)
.on('end', resolve)
child.on('error', reject)
})
} }
export async function getGitTimestamp(file: string): Promise<number> { export async function getGitTimestamp(file: string): Promise<number> {
@ -148,7 +143,6 @@ export async function getGitTimestamp(file: string): Promise<number> {
if (!fs.existsSync(file)) return 0 if (!fs.existsSync(file)) return 0
return new Promise((resolve, reject) => {
const child = spawn( const child = spawn(
'git', 'git',
['log', '-1', '--pretty=%at', '--', path.basename(file)], ['log', '-1', '--pretty=%at', '--', path.basename(file)],
@ -157,15 +151,11 @@ export async function getGitTimestamp(file: string): Promise<number> {
let output = '' let output = ''
child.stdout.on('data', (d) => (output += String(d))) child.stdout.on('data', (d) => (output += String(d)))
await once(child, 'close')
child.on('close', () => {
const ts = Number.parseInt(output.trim(), 10) * 1000 const ts = Number.parseInt(output.trim(), 10) * 1000
if (!(ts > 0)) return resolve(0) if (!(ts > 0)) return 0
cache.set(file, ts) cache.set(file, ts)
resolve(ts) return ts
})
child.on('error', reject)
})
} }

Loading…
Cancel
Save