mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
fix(list-files): surface top-level symlinked files in non-recursive mode and only follow symlinks when recursive=true
This commit is contained in:
parent
3c60c6e290
commit
d938fb6307
1 changed files with 40 additions and 5 deletions
|
|
@ -47,13 +47,16 @@ export async function listFiles(dirPath: string, recursive: boolean, limit: numb
|
|||
const rgPath = await getRipgrepPath()
|
||||
|
||||
if (!recursive) {
|
||||
// For non-recursive, use the existing approach
|
||||
// For non-recursive, include top-level files plus top-level symlinked files
|
||||
const files = await listFilesWithRipgrep(rgPath, dirPath, false, limit)
|
||||
const symlinkFiles = await listTopLevelSymlinkFiles(dirPath)
|
||||
const mergedFiles = [...files, ...symlinkFiles]
|
||||
|
||||
const ignoreInstance = await createIgnoreInstance(dirPath)
|
||||
// Calculate remaining limit for directories
|
||||
const remainingLimit = Math.max(0, limit - files.length)
|
||||
// Calculate remaining limit for directories after accounting for files
|
||||
const remainingLimit = Math.max(0, limit - mergedFiles.length)
|
||||
const directories = await listFilteredDirectories(dirPath, false, ignoreInstance, remainingLimit)
|
||||
return formatAndCombineResults(files, directories, limit)
|
||||
return formatAndCombineResults(mergedFiles, directories, limit)
|
||||
}
|
||||
|
||||
// For recursive mode, use the original approach but ensure first-level directories are included
|
||||
|
|
@ -212,15 +215,47 @@ async function listFilesWithRipgrep(
|
|||
const absolutePath = path.resolve(dirPath)
|
||||
return relativePaths.map((relativePath) => path.resolve(absolutePath, relativePath))
|
||||
}
|
||||
/**
|
||||
* List top-level symlinked files in a directory (non-recursive).
|
||||
* We include the symlink path itself if it points to a file, or if it's a broken link.
|
||||
*/
|
||||
async function listTopLevelSymlinkFiles(dirPath: string): Promise<string[]> {
|
||||
const absolutePath = path.resolve(dirPath)
|
||||
try {
|
||||
const entries = await fs.promises.readdir(absolutePath, { withFileTypes: true })
|
||||
const results: string[] = []
|
||||
for (const entry of entries) {
|
||||
if (entry.isSymbolicLink()) {
|
||||
const symlinkPath = path.join(absolutePath, entry.name)
|
||||
try {
|
||||
// stat follows the symlink
|
||||
const targetStat = await fs.promises.stat(symlinkPath)
|
||||
if (targetStat.isFile()) {
|
||||
results.push(symlinkPath)
|
||||
}
|
||||
} catch {
|
||||
// Broken symlink - still surface the symlink path so it is visible to the user
|
||||
results.push(symlinkPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
return results
|
||||
} catch {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build appropriate ripgrep arguments based on whether we're doing a recursive search
|
||||
*/
|
||||
function buildRipgrepArgs(dirPath: string, recursive: boolean): string[] {
|
||||
// Base arguments to list files
|
||||
const args = ["--files", "--hidden", "--follow"]
|
||||
// Note: do NOT follow symlinks in non-recursive mode so that symlinked files themselves are listed.
|
||||
// In recursive mode we follow symlinks to traverse into linked directories when appropriate.
|
||||
const args = ["--files", "--hidden"]
|
||||
|
||||
if (recursive) {
|
||||
args.push("--follow")
|
||||
return [...args, ...buildRecursiveArgs(dirPath), dirPath]
|
||||
} else {
|
||||
return [...args, ...buildNonRecursiveArgs(), dirPath]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue