mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-12 21:03:05 -07:00
feat(filesearch): Introduce non-recursive file search strategy (#6087)
Co-authored-by: Jacob Richman <jacob314@gmail.com> Co-authored-by: Bryant Chandler <bryantchandler@chromium.org>
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import path from 'node:path';
|
||||
import { fdir } from 'fdir';
|
||||
import { Ignore } from './ignore.js';
|
||||
import * as cache from './crawlCache.js';
|
||||
|
||||
export interface CrawlOptions {
|
||||
// The directory to start the crawl from.
|
||||
crawlDirectory: string;
|
||||
// The project's root directory, for path relativity.
|
||||
cwd: string;
|
||||
// The fdir maxDepth option.
|
||||
maxDepth?: number;
|
||||
// A pre-configured Ignore instance.
|
||||
ignore: Ignore;
|
||||
// Caching options.
|
||||
cache: boolean;
|
||||
cacheTtl: number;
|
||||
}
|
||||
|
||||
function toPosixPath(p: string) {
|
||||
return p.split(path.sep).join(path.posix.sep);
|
||||
}
|
||||
|
||||
export async function crawl(options: CrawlOptions): Promise<string[]> {
|
||||
if (options.cache) {
|
||||
const cacheKey = cache.getCacheKey(
|
||||
options.crawlDirectory,
|
||||
options.ignore.getFingerprint(),
|
||||
options.maxDepth,
|
||||
);
|
||||
const cachedResults = cache.read(cacheKey);
|
||||
|
||||
if (cachedResults) {
|
||||
return cachedResults;
|
||||
}
|
||||
}
|
||||
|
||||
const posixCwd = toPosixPath(options.cwd);
|
||||
const posixCrawlDirectory = toPosixPath(options.crawlDirectory);
|
||||
|
||||
let results: string[];
|
||||
try {
|
||||
const dirFilter = options.ignore.getDirectoryFilter();
|
||||
const api = new fdir()
|
||||
.withRelativePaths()
|
||||
.withDirs()
|
||||
.withPathSeparator('/') // Always use unix style paths
|
||||
.exclude((_, dirPath) => {
|
||||
const relativePath = path.posix.relative(posixCrawlDirectory, dirPath);
|
||||
return dirFilter(`${relativePath}/`);
|
||||
});
|
||||
|
||||
if (options.maxDepth !== undefined) {
|
||||
api.withMaxDepth(options.maxDepth);
|
||||
}
|
||||
|
||||
results = await api.crawl(options.crawlDirectory).withPromise();
|
||||
} catch (_e) {
|
||||
// The directory probably doesn't exist.
|
||||
return [];
|
||||
}
|
||||
|
||||
const relativeToCrawlDir = path.posix.relative(posixCwd, posixCrawlDirectory);
|
||||
|
||||
const relativeToCwdResults = results.map((p) =>
|
||||
path.posix.join(relativeToCrawlDir, p),
|
||||
);
|
||||
|
||||
if (options.cache) {
|
||||
const cacheKey = cache.getCacheKey(
|
||||
options.crawlDirectory,
|
||||
options.ignore.getFingerprint(),
|
||||
options.maxDepth,
|
||||
);
|
||||
cache.write(cacheKey, relativeToCwdResults, options.cacheTtl * 1000);
|
||||
}
|
||||
|
||||
return relativeToCwdResults;
|
||||
}
|
||||
Reference in New Issue
Block a user