initialize `FileDiscoveryService` once (#1029)
This commit is contained in:
parent
209381f06f
commit
8eb505fbba
|
@ -33,7 +33,8 @@ vi.mock('@gemini-cli/core', async () => {
|
||||||
return {
|
return {
|
||||||
...actualServer,
|
...actualServer,
|
||||||
loadEnvironment: vi.fn(),
|
loadEnvironment: vi.fn(),
|
||||||
loadServerHierarchicalMemory: vi.fn((cwd, debug, extensionPaths) =>
|
loadServerHierarchicalMemory: vi.fn(
|
||||||
|
(cwd, debug, fileService, extensionPaths) =>
|
||||||
Promise.resolve({
|
Promise.resolve({
|
||||||
memoryContent: extensionPaths?.join(',') || '',
|
memoryContent: extensionPaths?.join(',') || '',
|
||||||
fileCount: extensionPaths?.length || 0,
|
fileCount: extensionPaths?.length || 0,
|
||||||
|
@ -239,6 +240,7 @@ describe('Hierarchical Memory Loading (config.ts) - Placeholder Suite', () => {
|
||||||
expect(ServerConfig.loadServerHierarchicalMemory).toHaveBeenCalledWith(
|
expect(ServerConfig.loadServerHierarchicalMemory).toHaveBeenCalledWith(
|
||||||
expect.any(String),
|
expect.any(String),
|
||||||
false,
|
false,
|
||||||
|
expect.any(Object),
|
||||||
[
|
[
|
||||||
'/path/to/ext1/GEMINI.md',
|
'/path/to/ext1/GEMINI.md',
|
||||||
'/path/to/ext3/context1.md',
|
'/path/to/ext3/context1.md',
|
||||||
|
|
|
@ -17,6 +17,7 @@ import {
|
||||||
GEMINI_CONFIG_DIR as GEMINI_DIR,
|
GEMINI_CONFIG_DIR as GEMINI_DIR,
|
||||||
DEFAULT_GEMINI_MODEL,
|
DEFAULT_GEMINI_MODEL,
|
||||||
DEFAULT_GEMINI_EMBEDDING_MODEL,
|
DEFAULT_GEMINI_EMBEDDING_MODEL,
|
||||||
|
FileDiscoveryService,
|
||||||
} from '@gemini-cli/core';
|
} from '@gemini-cli/core';
|
||||||
import { Settings } from './settings.js';
|
import { Settings } from './settings.js';
|
||||||
import { getEffectiveModel } from '../utils/modelCheck.js';
|
import { getEffectiveModel } from '../utils/modelCheck.js';
|
||||||
|
@ -114,6 +115,7 @@ async function parseArguments(): Promise<CliArgs> {
|
||||||
export async function loadHierarchicalGeminiMemory(
|
export async function loadHierarchicalGeminiMemory(
|
||||||
currentWorkingDirectory: string,
|
currentWorkingDirectory: string,
|
||||||
debugMode: boolean,
|
debugMode: boolean,
|
||||||
|
fileService: FileDiscoveryService,
|
||||||
extensionContextFilePaths: string[] = [],
|
extensionContextFilePaths: string[] = [],
|
||||||
): Promise<{ memoryContent: string; fileCount: number }> {
|
): Promise<{ memoryContent: string; fileCount: number }> {
|
||||||
if (debugMode) {
|
if (debugMode) {
|
||||||
|
@ -126,6 +128,7 @@ export async function loadHierarchicalGeminiMemory(
|
||||||
return loadServerHierarchicalMemory(
|
return loadServerHierarchicalMemory(
|
||||||
currentWorkingDirectory,
|
currentWorkingDirectory,
|
||||||
debugMode,
|
debugMode,
|
||||||
|
fileService,
|
||||||
extensionContextFilePaths,
|
extensionContextFilePaths,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -154,10 +157,15 @@ export async function loadCliConfig(
|
||||||
|
|
||||||
const extensionContextFilePaths = extensions.flatMap((e) => e.contextFiles);
|
const extensionContextFilePaths = extensions.flatMap((e) => e.contextFiles);
|
||||||
|
|
||||||
|
const fileService = new FileDiscoveryService(process.cwd());
|
||||||
|
await fileService.initialize({
|
||||||
|
respectGitIgnore: settings.fileFiltering?.respectGitIgnore,
|
||||||
|
});
|
||||||
// Call the (now wrapper) loadHierarchicalGeminiMemory which calls the server's version
|
// Call the (now wrapper) loadHierarchicalGeminiMemory which calls the server's version
|
||||||
const { memoryContent, fileCount } = await loadHierarchicalGeminiMemory(
|
const { memoryContent, fileCount } = await loadHierarchicalGeminiMemory(
|
||||||
process.cwd(),
|
process.cwd(),
|
||||||
debugMode,
|
debugMode,
|
||||||
|
fileService,
|
||||||
extensionContextFilePaths,
|
extensionContextFilePaths,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -201,6 +209,7 @@ export async function loadCliConfig(
|
||||||
process.env.http_proxy,
|
process.env.http_proxy,
|
||||||
cwd: process.cwd(),
|
cwd: process.cwd(),
|
||||||
telemetryOtlpEndpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
|
telemetryOtlpEndpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
|
||||||
|
fileDiscoveryService: fileService,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -139,6 +139,7 @@ const App = ({ config, settings, startupWarnings = [] }: AppProps) => {
|
||||||
const { memoryContent, fileCount } = await loadHierarchicalGeminiMemory(
|
const { memoryContent, fileCount } = await loadHierarchicalGeminiMemory(
|
||||||
process.cwd(),
|
process.cwd(),
|
||||||
config.getDebugMode(),
|
config.getDebugMode(),
|
||||||
|
await config.getFileService(),
|
||||||
);
|
);
|
||||||
config.setUserMemory(memoryContent);
|
config.setUserMemory(memoryContent);
|
||||||
config.setGeminiMdFileCount(fileCount);
|
config.setGeminiMdFileCount(fileCount);
|
||||||
|
|
|
@ -86,6 +86,7 @@ export interface ConfigParameters {
|
||||||
checkpoint?: boolean;
|
checkpoint?: boolean;
|
||||||
proxy?: string;
|
proxy?: string;
|
||||||
cwd: string;
|
cwd: string;
|
||||||
|
fileDiscoveryService?: FileDiscoveryService;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Config {
|
export class Config {
|
||||||
|
@ -152,6 +153,7 @@ export class Config {
|
||||||
this.checkpoint = params.checkpoint ?? false;
|
this.checkpoint = params.checkpoint ?? false;
|
||||||
this.proxy = params.proxy;
|
this.proxy = params.proxy;
|
||||||
this.cwd = params.cwd ?? process.cwd();
|
this.cwd = params.cwd ?? process.cwd();
|
||||||
|
this.fileDiscoveryService = params.fileDiscoveryService ?? null;
|
||||||
|
|
||||||
if (params.contextFileName) {
|
if (params.contextFileName) {
|
||||||
setGeminiMdFilename(params.contextFileName);
|
setGeminiMdFilename(params.contextFileName);
|
||||||
|
|
|
@ -47,14 +47,17 @@ export class GitIgnoreParser implements GitIgnoreFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadPatterns(patternsFileName: string): Promise<void> {
|
async loadPatterns(patternsFileName: string): Promise<void> {
|
||||||
const content = await fs.readFile(
|
const patternsFilePath = path.join(this.projectRoot, patternsFileName);
|
||||||
path.join(this.projectRoot, patternsFileName),
|
const content = await fs.readFile(patternsFilePath, 'utf-8');
|
||||||
'utf-8',
|
|
||||||
);
|
|
||||||
const patterns = content
|
const patterns = content
|
||||||
.split('\n')
|
.split('\n')
|
||||||
.map((p) => p.trim())
|
.map((p) => p.trim())
|
||||||
.filter((p) => p !== '' && !p.startsWith('#'));
|
.filter((p) => p !== '' && !p.startsWith('#'));
|
||||||
|
if (patterns.length > 0) {
|
||||||
|
console.log(
|
||||||
|
`Loaded ${patterns.length} patterns from ${patternsFilePath}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
this.addPatterns(patterns);
|
this.addPatterns(patterns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ import {
|
||||||
getCurrentGeminiMdFilename,
|
getCurrentGeminiMdFilename,
|
||||||
DEFAULT_CONTEXT_FILENAME,
|
DEFAULT_CONTEXT_FILENAME,
|
||||||
} from '../tools/memoryTool.js';
|
} from '../tools/memoryTool.js';
|
||||||
|
import { FileDiscoveryService } from '../services/fileDiscoveryService.js';
|
||||||
|
|
||||||
const ORIGINAL_GEMINI_MD_FILENAME_CONST_FOR_TEST = DEFAULT_CONTEXT_FILENAME;
|
const ORIGINAL_GEMINI_MD_FILENAME_CONST_FOR_TEST = DEFAULT_CONTEXT_FILENAME;
|
||||||
|
|
||||||
|
@ -43,6 +44,7 @@ describe('loadServerHierarchicalMemory', () => {
|
||||||
let GLOBAL_GEMINI_DIR: string;
|
let GLOBAL_GEMINI_DIR: string;
|
||||||
let GLOBAL_GEMINI_FILE: string; // Defined in beforeEach
|
let GLOBAL_GEMINI_FILE: string; // Defined in beforeEach
|
||||||
|
|
||||||
|
const fileService = new FileDiscoveryService(PROJECT_ROOT);
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.resetAllMocks();
|
vi.resetAllMocks();
|
||||||
// Set environment variables to indicate test environment
|
// Set environment variables to indicate test environment
|
||||||
|
@ -69,6 +71,7 @@ describe('loadServerHierarchicalMemory', () => {
|
||||||
const { memoryContent, fileCount } = await loadServerHierarchicalMemory(
|
const { memoryContent, fileCount } = await loadServerHierarchicalMemory(
|
||||||
CWD,
|
CWD,
|
||||||
false,
|
false,
|
||||||
|
fileService,
|
||||||
);
|
);
|
||||||
expect(memoryContent).toBe('');
|
expect(memoryContent).toBe('');
|
||||||
expect(fileCount).toBe(0);
|
expect(fileCount).toBe(0);
|
||||||
|
@ -95,6 +98,7 @@ describe('loadServerHierarchicalMemory', () => {
|
||||||
const { memoryContent, fileCount } = await loadServerHierarchicalMemory(
|
const { memoryContent, fileCount } = await loadServerHierarchicalMemory(
|
||||||
CWD,
|
CWD,
|
||||||
false,
|
false,
|
||||||
|
fileService,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(memoryContent).toBe(
|
expect(memoryContent).toBe(
|
||||||
|
@ -125,6 +129,7 @@ describe('loadServerHierarchicalMemory', () => {
|
||||||
const { memoryContent, fileCount } = await loadServerHierarchicalMemory(
|
const { memoryContent, fileCount } = await loadServerHierarchicalMemory(
|
||||||
CWD,
|
CWD,
|
||||||
false,
|
false,
|
||||||
|
fileService,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(memoryContent).toBe(
|
expect(memoryContent).toBe(
|
||||||
|
@ -167,6 +172,7 @@ describe('loadServerHierarchicalMemory', () => {
|
||||||
const { memoryContent, fileCount } = await loadServerHierarchicalMemory(
|
const { memoryContent, fileCount } = await loadServerHierarchicalMemory(
|
||||||
CWD,
|
CWD,
|
||||||
false,
|
false,
|
||||||
|
fileService,
|
||||||
);
|
);
|
||||||
const expectedContent =
|
const expectedContent =
|
||||||
`--- Context from: ${path.relative(CWD, projectRootCustomFile)} ---\nProject root custom memory\n--- End of Context from: ${path.relative(CWD, projectRootCustomFile)} ---\n\n` +
|
`--- Context from: ${path.relative(CWD, projectRootCustomFile)} ---\nProject root custom memory\n--- End of Context from: ${path.relative(CWD, projectRootCustomFile)} ---\n\n` +
|
||||||
|
@ -231,6 +237,7 @@ describe('loadServerHierarchicalMemory', () => {
|
||||||
const { memoryContent, fileCount } = await loadServerHierarchicalMemory(
|
const { memoryContent, fileCount } = await loadServerHierarchicalMemory(
|
||||||
CWD,
|
CWD,
|
||||||
false,
|
false,
|
||||||
|
fileService,
|
||||||
);
|
);
|
||||||
const expectedContent =
|
const expectedContent =
|
||||||
`--- Context from: ${customFilename} ---\nCWD custom memory\n--- End of Context from: ${customFilename} ---\n\n` +
|
`--- Context from: ${customFilename} ---\nCWD custom memory\n--- End of Context from: ${customFilename} ---\n\n` +
|
||||||
|
@ -277,6 +284,7 @@ describe('loadServerHierarchicalMemory', () => {
|
||||||
const { memoryContent, fileCount } = await loadServerHierarchicalMemory(
|
const { memoryContent, fileCount } = await loadServerHierarchicalMemory(
|
||||||
CWD,
|
CWD,
|
||||||
false,
|
false,
|
||||||
|
fileService,
|
||||||
);
|
);
|
||||||
const expectedContent =
|
const expectedContent =
|
||||||
`--- Context from: ${path.relative(CWD, projectRootGeminiFile)} ---\nProject root memory\n--- End of Context from: ${path.relative(CWD, projectRootGeminiFile)} ---\n\n` +
|
`--- Context from: ${path.relative(CWD, projectRootGeminiFile)} ---\nProject root memory\n--- End of Context from: ${path.relative(CWD, projectRootGeminiFile)} ---\n\n` +
|
||||||
|
@ -345,6 +353,7 @@ describe('loadServerHierarchicalMemory', () => {
|
||||||
const { memoryContent, fileCount } = await loadServerHierarchicalMemory(
|
const { memoryContent, fileCount } = await loadServerHierarchicalMemory(
|
||||||
CWD,
|
CWD,
|
||||||
false,
|
false,
|
||||||
|
fileService,
|
||||||
);
|
);
|
||||||
const expectedContent =
|
const expectedContent =
|
||||||
`--- Context from: ${ORIGINAL_GEMINI_MD_FILENAME_CONST_FOR_TEST} ---\nCWD memory\n--- End of Context from: ${ORIGINAL_GEMINI_MD_FILENAME_CONST_FOR_TEST} ---\n\n` +
|
`--- Context from: ${ORIGINAL_GEMINI_MD_FILENAME_CONST_FOR_TEST} ---\nCWD memory\n--- End of Context from: ${ORIGINAL_GEMINI_MD_FILENAME_CONST_FOR_TEST} ---\n\n` +
|
||||||
|
@ -438,6 +447,7 @@ describe('loadServerHierarchicalMemory', () => {
|
||||||
const { memoryContent, fileCount } = await loadServerHierarchicalMemory(
|
const { memoryContent, fileCount } = await loadServerHierarchicalMemory(
|
||||||
CWD,
|
CWD,
|
||||||
false,
|
false,
|
||||||
|
fileService,
|
||||||
);
|
);
|
||||||
|
|
||||||
const relPathGlobal = path.relative(CWD, GLOBAL_GEMINI_FILE);
|
const relPathGlobal = path.relative(CWD, GLOBAL_GEMINI_FILE);
|
||||||
|
@ -520,6 +530,7 @@ describe('loadServerHierarchicalMemory', () => {
|
||||||
const { memoryContent, fileCount } = await loadServerHierarchicalMemory(
|
const { memoryContent, fileCount } = await loadServerHierarchicalMemory(
|
||||||
CWD,
|
CWD,
|
||||||
false,
|
false,
|
||||||
|
fileService,
|
||||||
);
|
);
|
||||||
|
|
||||||
const expectedContent = `--- Context from: ${path.join('my_code', ORIGINAL_GEMINI_MD_FILENAME_CONST_FOR_TEST)} ---\nMy code memory\n--- End of Context from: ${path.join('my_code', ORIGINAL_GEMINI_MD_FILENAME_CONST_FOR_TEST)} ---`;
|
const expectedContent = `--- Context from: ${path.join('my_code', ORIGINAL_GEMINI_MD_FILENAME_CONST_FOR_TEST)} ---\nMy code memory\n--- End of Context from: ${path.join('my_code', ORIGINAL_GEMINI_MD_FILENAME_CONST_FOR_TEST)} ---`;
|
||||||
|
@ -556,7 +567,7 @@ describe('loadServerHierarchicalMemory', () => {
|
||||||
}) as unknown as typeof fsPromises.readdir);
|
}) as unknown as typeof fsPromises.readdir);
|
||||||
mockFs.access.mockRejectedValue(new Error('not found'));
|
mockFs.access.mockRejectedValue(new Error('not found'));
|
||||||
|
|
||||||
await loadServerHierarchicalMemory(CWD, true);
|
await loadServerHierarchicalMemory(CWD, true, fileService);
|
||||||
|
|
||||||
expect(consoleDebugSpy).toHaveBeenCalledWith(
|
expect(consoleDebugSpy).toHaveBeenCalledWith(
|
||||||
expect.stringContaining('[DEBUG] [BfsFileSearch]'),
|
expect.stringContaining('[DEBUG] [BfsFileSearch]'),
|
||||||
|
@ -583,6 +594,7 @@ describe('loadServerHierarchicalMemory', () => {
|
||||||
const { memoryContent, fileCount } = await loadServerHierarchicalMemory(
|
const { memoryContent, fileCount } = await loadServerHierarchicalMemory(
|
||||||
CWD,
|
CWD,
|
||||||
false,
|
false,
|
||||||
|
fileService,
|
||||||
[extensionFilePath],
|
[extensionFilePath],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,7 @@ async function getGeminiMdFilePathsInternal(
|
||||||
currentWorkingDirectory: string,
|
currentWorkingDirectory: string,
|
||||||
userHomePath: string,
|
userHomePath: string,
|
||||||
debugMode: boolean,
|
debugMode: boolean,
|
||||||
|
fileService: FileDiscoveryService,
|
||||||
extensionContextFilePaths: string[] = [],
|
extensionContextFilePaths: string[] = [],
|
||||||
): Promise<string[]> {
|
): Promise<string[]> {
|
||||||
const allPaths = new Set<string>();
|
const allPaths = new Set<string>();
|
||||||
|
@ -179,8 +180,6 @@ async function getGeminiMdFilePathsInternal(
|
||||||
}
|
}
|
||||||
upwardPaths.forEach((p) => allPaths.add(p));
|
upwardPaths.forEach((p) => allPaths.add(p));
|
||||||
|
|
||||||
const fileService = new FileDiscoveryService(projectRoot || resolvedCwd);
|
|
||||||
await fileService.initialize();
|
|
||||||
const downwardPaths = await bfsFileSearch(resolvedCwd, {
|
const downwardPaths = await bfsFileSearch(resolvedCwd, {
|
||||||
fileName: geminiMdFilename,
|
fileName: geminiMdFilename,
|
||||||
maxDirs: MAX_DIRECTORIES_TO_SCAN_FOR_MEMORY,
|
maxDirs: MAX_DIRECTORIES_TO_SCAN_FOR_MEMORY,
|
||||||
|
@ -272,6 +271,7 @@ function concatenateInstructions(
|
||||||
export async function loadServerHierarchicalMemory(
|
export async function loadServerHierarchicalMemory(
|
||||||
currentWorkingDirectory: string,
|
currentWorkingDirectory: string,
|
||||||
debugMode: boolean,
|
debugMode: boolean,
|
||||||
|
fileService: FileDiscoveryService,
|
||||||
extensionContextFilePaths: string[] = [],
|
extensionContextFilePaths: string[] = [],
|
||||||
): Promise<{ memoryContent: string; fileCount: number }> {
|
): Promise<{ memoryContent: string; fileCount: number }> {
|
||||||
if (debugMode)
|
if (debugMode)
|
||||||
|
@ -285,6 +285,7 @@ export async function loadServerHierarchicalMemory(
|
||||||
currentWorkingDirectory,
|
currentWorkingDirectory,
|
||||||
userHomePath,
|
userHomePath,
|
||||||
debugMode,
|
debugMode,
|
||||||
|
fileService,
|
||||||
extensionContextFilePaths,
|
extensionContextFilePaths,
|
||||||
);
|
);
|
||||||
if (filePaths.length === 0) {
|
if (filePaths.length === 0) {
|
||||||
|
|
Loading…
Reference in New Issue