mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-24 20:14:44 -07:00
feat(core): populate sandbox forbidden paths with project ignore file contents (#24038)
This commit is contained in:
@@ -253,6 +253,10 @@ vi.mock('../core/tokenLimits.js', () => ({
|
||||
vi.mock('../code_assist/codeAssist.js');
|
||||
vi.mock('../code_assist/experiments/experiments.js');
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('Server Config (config.ts)', () => {
|
||||
const MODEL = DEFAULT_GEMINI_MODEL;
|
||||
const SANDBOX: SandboxConfig = createMockSandboxConfig({
|
||||
@@ -1613,6 +1617,31 @@ describe('Server Config (config.ts)', () => {
|
||||
expect(config.getSandboxAllowedPaths()).toEqual(['/only/this']);
|
||||
expect(config.getSandboxNetworkAccess()).toBe(false);
|
||||
});
|
||||
|
||||
it('lazily resolves forbidden paths when first accessed', async () => {
|
||||
const config = new Config({
|
||||
...baseParams,
|
||||
sandbox: { enabled: true, command: 'docker' },
|
||||
});
|
||||
|
||||
const fileService = config.getFileService();
|
||||
vi.spyOn(fileService, 'getIgnoredPaths').mockResolvedValue([
|
||||
'/tmp/forbidden',
|
||||
]);
|
||||
|
||||
await config.initialize();
|
||||
expect(fileService.getIgnoredPaths).not.toHaveBeenCalled();
|
||||
|
||||
// Access resolved paths via the internal resolver
|
||||
const resolved = await (
|
||||
config as unknown as {
|
||||
getSandboxForbiddenPaths: () => Promise<string[]>;
|
||||
}
|
||||
).getSandboxForbiddenPaths();
|
||||
|
||||
expect(fileService.getIgnoredPaths).toHaveBeenCalled();
|
||||
expect(resolved).toEqual(['/tmp/forbidden']);
|
||||
});
|
||||
});
|
||||
|
||||
it('should have independent TopicState across instances', () => {
|
||||
|
||||
@@ -758,6 +758,7 @@ export class Config implements McpContext, AgentLoopContext {
|
||||
readonly modelConfigService: ModelConfigService;
|
||||
private readonly embeddingModel: string;
|
||||
private readonly sandbox: SandboxConfig | undefined;
|
||||
private _sandboxForbiddenPaths: string[] | undefined;
|
||||
private readonly targetDir: string;
|
||||
private workspaceContext: WorkspaceContext;
|
||||
private readonly debugMode: boolean;
|
||||
@@ -997,6 +998,7 @@ export class Config implements McpContext, AgentLoopContext {
|
||||
this.sandbox,
|
||||
{
|
||||
workspace: this.targetDir,
|
||||
forbiddenPaths: this.getSandboxForbiddenPaths.bind(this),
|
||||
includeDirectories: this.pendingIncludeDirectories,
|
||||
policyManager: this._sandboxPolicyManager,
|
||||
},
|
||||
@@ -1678,11 +1680,25 @@ export class Config implements McpContext, AgentLoopContext {
|
||||
return this._geminiClient;
|
||||
}
|
||||
|
||||
private async getSandboxForbiddenPaths(): Promise<string[]> {
|
||||
if (this._sandboxForbiddenPaths) {
|
||||
return this._sandboxForbiddenPaths;
|
||||
}
|
||||
|
||||
this._sandboxForbiddenPaths = await this.getFileService().getIgnoredPaths({
|
||||
respectGitIgnore: false,
|
||||
respectGeminiIgnore: true,
|
||||
});
|
||||
|
||||
return this._sandboxForbiddenPaths;
|
||||
}
|
||||
|
||||
private refreshSandboxManager(): void {
|
||||
this._sandboxManager = createSandboxManager(
|
||||
this.sandbox,
|
||||
{
|
||||
workspace: this.targetDir,
|
||||
forbiddenPaths: this.getSandboxForbiddenPaths.bind(this),
|
||||
policyManager: this._sandboxPolicyManager,
|
||||
},
|
||||
this.getApprovalMode(),
|
||||
|
||||
Reference in New Issue
Block a user