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()) for (const file of rec.files) {
.on('data', (rec: GitLogRecord) => { const slashed = slash(path.resolve(gitRoot, file))
for (const file of rec.files) { if (!cache.has(slashed)) cache.set(slashed, rec.ts)
const slashed = slash(path.resolve(gitRoot, file)) }
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,24 +143,19 @@ 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)], { cwd: path.dirname(file) }
{ cwd: path.dirname(file) } )
)
let output = ''
child.stdout.on('data', (d) => (output += String(d)))
child.on('close', () => { let output = ''
const ts = Number.parseInt(output.trim(), 10) * 1000 child.stdout.on('data', (d) => (output += String(d)))
if (!(ts > 0)) return resolve(0) await once(child, 'close')
cache.set(file, ts) const ts = Number.parseInt(output.trim(), 10) * 1000
resolve(ts) if (!(ts > 0)) return 0
})
child.on('error', reject) cache.set(file, ts)
}) return ts
} }

Loading…
Cancel
Save