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/5341/head
Divyansh Singh 1 week ago
parent d50b29da61
commit 898f5d41c1

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

Loading…
Cancel
Save