perf: avoid stat fanout in nested repo scans (#4276)
This commit is contained in:
parent
eb7c9fac2d
commit
f3ba73d845
|
|
@ -1,4 +1,4 @@
|
|||
import { mkdtemp, mkdir, writeFile, rm } from 'fs/promises'
|
||||
import { mkdtemp, mkdir, writeFile, rm, symlink } from 'fs/promises'
|
||||
import { join } from 'path'
|
||||
import { tmpdir } from 'os'
|
||||
import { afterEach, describe, expect, it } from 'vitest'
|
||||
|
|
@ -76,4 +76,19 @@ describe('scanNestedRepos', () => {
|
|||
expect(result.selectedPathKind).toBe('git_repo')
|
||||
expect(result.repos).toEqual([])
|
||||
})
|
||||
|
||||
it.skipIf(process.platform === 'win32')(
|
||||
'does not follow symlinked directories outside the selected folder',
|
||||
async () => {
|
||||
const root = await tempRoot()
|
||||
const external = await tempRoot()
|
||||
await mkdir(join(external, 'outside-repo'), { recursive: true })
|
||||
await makeGitRepo(join(external, 'outside-repo'))
|
||||
await symlink(external, join(root, 'linked'), 'dir')
|
||||
|
||||
const result = await scanNestedRepos({ path: root })
|
||||
|
||||
expect(result.repos).toEqual([])
|
||||
}
|
||||
)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -70,13 +70,10 @@ async function hasGitMarker(dirPath: string): Promise<boolean> {
|
|||
}
|
||||
|
||||
async function readLocalDirectory(dirPath: string): Promise<NestedRepoDirectoryEntry[]> {
|
||||
const entries = await readdir(dirPath)
|
||||
const result: NestedRepoDirectoryEntry[] = []
|
||||
for (const name of entries) {
|
||||
const childStat = await stat(join(dirPath, name)).catch(() => null)
|
||||
result.push({ name, isDirectory: childStat?.isDirectory() === true })
|
||||
}
|
||||
return result
|
||||
// Why: Dirent data avoids one stat per child and keeps symlinked directories
|
||||
// from expanding the scan outside the selected folder.
|
||||
const entries = await readdir(dirPath, { withFileTypes: true })
|
||||
return entries.map((entry) => ({ name: entry.name, isDirectory: entry.isDirectory() }))
|
||||
}
|
||||
|
||||
export async function scanNestedRepos(args: {
|
||||
|
|
|
|||
Loading…
Reference in New Issue