summaryrefslogtreecommitdiff
path: root/packages/core/src
diff options
context:
space:
mode:
authorAbhi <[email protected]>2025-07-14 13:23:51 -0400
committerGitHub <[email protected]>2025-07-14 17:23:51 +0000
commit9dc812dd4b90008575e747e9a821feddd2c4dc49 (patch)
tree23c293f7f6611efd6a38d705d700e240c42f11b8 /packages/core/src
parent2f1d6234def2c8c77c2afebd9f83a2dcf3d6aacd (diff)
fix(checkpoint): Prevent silent failure and enable for non-Git projects (#4144)
Diffstat (limited to 'packages/core/src')
-rw-r--r--packages/core/src/config/config.test.ts33
-rw-r--r--packages/core/src/config/config.ts6
-rw-r--r--packages/core/src/services/gitService.test.ts10
-rw-r--r--packages/core/src/services/gitService.ts8
4 files changed, 38 insertions, 19 deletions
diff --git a/packages/core/src/config/config.test.ts b/packages/core/src/config/config.test.ts
index c9965e87..bb074a71 100644
--- a/packages/core/src/config/config.test.ts
+++ b/packages/core/src/config/config.test.ts
@@ -17,6 +17,7 @@ import {
createContentGeneratorConfig,
} from '../core/contentGenerator.js';
import { GeminiClient } from '../core/client.js';
+import { GitService } from '../services/gitService.js';
import { loadServerHierarchicalMemory } from '../utils/memoryDiscovery.js';
// Mock dependencies that might be called during Config construction or createServerConfig
@@ -75,6 +76,12 @@ vi.mock('../telemetry/index.js', async (importOriginal) => {
};
});
+vi.mock('../services/gitService.js', () => {
+ const GitServiceMock = vi.fn();
+ GitServiceMock.prototype.initialize = vi.fn();
+ return { GitService: GitServiceMock };
+});
+
describe('Server Config (config.ts)', () => {
const MODEL = 'gemini-pro';
const SANDBOX: SandboxConfig = {
@@ -108,6 +115,32 @@ describe('Server Config (config.ts)', () => {
vi.clearAllMocks();
});
+ describe('initialize', () => {
+ it('should throw an error if checkpointing is enabled and GitService fails', async () => {
+ const gitError = new Error('Git is not installed');
+ (GitService.prototype.initialize as Mock).mockRejectedValue(gitError);
+
+ const config = new Config({
+ ...baseParams,
+ checkpointing: true,
+ });
+
+ await expect(config.initialize()).rejects.toThrow(gitError);
+ });
+
+ it('should not throw an error if checkpointing is disabled and GitService fails', async () => {
+ const gitError = new Error('Git is not installed');
+ (GitService.prototype.initialize as Mock).mockRejectedValue(gitError);
+
+ const config = new Config({
+ ...baseParams,
+ checkpointing: false,
+ });
+
+ await expect(config.initialize()).resolves.toBeUndefined();
+ });
+ });
+
describe('refreshAuth', () => {
it('should refresh auth and update config', async () => {
const config = new Config(baseParams);
diff --git a/packages/core/src/config/config.ts b/packages/core/src/config/config.ts
index 7d982385..1b101815 100644
--- a/packages/core/src/config/config.ts
+++ b/packages/core/src/config/config.ts
@@ -259,11 +259,7 @@ export class Config {
// Initialize centralized FileDiscoveryService
this.getFileService();
if (this.getCheckpointingEnabled()) {
- try {
- await this.getGitService();
- } catch {
- // For now swallow the error, later log it.
- }
+ await this.getGitService();
}
this.toolRegistry = await this.createToolRegistry();
}
diff --git a/packages/core/src/services/gitService.test.ts b/packages/core/src/services/gitService.test.ts
index d0b991a3..d23b0737 100644
--- a/packages/core/src/services/gitService.test.ts
+++ b/packages/core/src/services/gitService.test.ts
@@ -154,14 +154,6 @@ describe('GitService', () => {
});
describe('initialize', () => {
- it('should throw an error if projectRoot is not a Git repository', async () => {
- hoistedIsGitRepositoryMock.mockReturnValue(false);
- const service = new GitService(mockProjectRoot);
- await expect(service.initialize()).rejects.toThrow(
- 'GitService requires a Git repository',
- );
- });
-
it('should throw an error if Git is not available', async () => {
hoistedMockExec.mockImplementation((command, callback) => {
callback(new Error('git not found'));
@@ -169,7 +161,7 @@ describe('GitService', () => {
});
const service = new GitService(mockProjectRoot);
await expect(service.initialize()).rejects.toThrow(
- 'GitService requires Git to be installed',
+ 'Checkpointing is enabled, but Git is not installed. Please install Git or disable checkpointing to continue.',
);
});
diff --git a/packages/core/src/services/gitService.ts b/packages/core/src/services/gitService.ts
index bd7b72fd..8b3fe46f 100644
--- a/packages/core/src/services/gitService.ts
+++ b/packages/core/src/services/gitService.ts
@@ -8,7 +8,6 @@ import * as fs from 'fs/promises';
import * as path from 'path';
import * as os from 'os';
import { isNodeError } from '../utils/errors.js';
-import { isGitRepository } from '../utils/gitUtils.js';
import { exec } from 'node:child_process';
import { simpleGit, SimpleGit, CheckRepoActions } from 'simple-git';
import { getProjectHash, GEMINI_DIR } from '../utils/paths.js';
@@ -26,12 +25,11 @@ export class GitService {
}
async initialize(): Promise<void> {
- if (!isGitRepository(this.projectRoot)) {
- throw new Error('GitService requires a Git repository');
- }
const gitAvailable = await this.verifyGitAvailability();
if (!gitAvailable) {
- throw new Error('GitService requires Git to be installed');
+ throw new Error(
+ 'Checkpointing is enabled, but Git is not installed. Please install Git or disable checkpointing to continue.',
+ );
}
this.setupShadowGitRepository();
}