Create ExtensionManager class which manages all high level extension tasks (#11667)

This commit is contained in:
Jacob MacDonald
2025-10-23 11:39:36 -07:00
committed by GitHub
parent 3a501196f0
commit c4c0c0d182
31 changed files with 1450 additions and 1568 deletions

View File

@@ -4,7 +4,15 @@
* SPDX-License-Identifier: Apache-2.0
*/
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import {
afterEach,
beforeEach,
describe,
expect,
it,
vi,
type MockedFunction,
} from 'vitest';
import {
checkForExtensionUpdate,
cloneFromGit,
@@ -22,7 +30,9 @@ import * as path from 'node:path';
import * as tar from 'tar';
import * as archiver from 'archiver';
import type { GeminiCLIExtension } from '@google/gemini-cli-core';
import { ExtensionEnablementManager } from './extensionEnablement.js';
import { ExtensionManager } from '../extension-manager.js';
import { loadSettings } from '../settings.js';
import type { ExtensionSetting } from './extensionSettings.js';
const mockPlatform = vi.hoisted(() => vi.fn());
const mockArch = vi.hoisted(() => vi.fn());
@@ -134,8 +144,34 @@ describe('git extension helpers', () => {
revparse: vi.fn(),
};
let extensionManager: ExtensionManager;
let mockRequestConsent: MockedFunction<
(consent: string) => Promise<boolean>
>;
let mockPromptForSettings: MockedFunction<
(setting: ExtensionSetting) => Promise<string>
>;
let tempHomeDir: string;
let tempWorkspaceDir: string;
beforeEach(() => {
tempHomeDir = fsSync.mkdtempSync(
path.join(os.tmpdir(), 'gemini-cli-test-home-'),
);
tempWorkspaceDir = fsSync.mkdtempSync(
path.join(tempHomeDir, 'gemini-cli-test-workspace-'),
);
vi.mocked(simpleGit).mockReturnValue(mockGit as unknown as SimpleGit);
mockRequestConsent = vi.fn();
mockRequestConsent.mockResolvedValue(true);
mockPromptForSettings = vi.fn();
mockPromptForSettings.mockResolvedValue('');
extensionManager = new ExtensionManager({
workspaceDir: tempWorkspaceDir,
requestConsent: mockRequestConsent,
requestSetting: mockPromptForSettings,
loadedSettings: loadSettings(tempWorkspaceDir),
});
});
it('should return NOT_UPDATABLE for non-git extensions', async () => {
@@ -151,10 +187,7 @@ describe('git extension helpers', () => {
},
contextFiles: [],
};
const result = await checkForExtensionUpdate(
extension,
new ExtensionEnablementManager(),
);
const result = await checkForExtensionUpdate(extension, extensionManager);
expect(result).toBe(ExtensionUpdateState.NOT_UPDATABLE);
});
@@ -172,10 +205,7 @@ describe('git extension helpers', () => {
contextFiles: [],
};
mockGit.getRemotes.mockResolvedValue([]);
const result = await checkForExtensionUpdate(
extension,
new ExtensionEnablementManager(),
);
const result = await checkForExtensionUpdate(extension, extensionManager);
expect(result).toBe(ExtensionUpdateState.ERROR);
});
@@ -198,10 +228,7 @@ describe('git extension helpers', () => {
mockGit.listRemote.mockResolvedValue('remote-hash\tHEAD');
mockGit.revparse.mockResolvedValue('local-hash');
const result = await checkForExtensionUpdate(
extension,
new ExtensionEnablementManager(),
);
const result = await checkForExtensionUpdate(extension, extensionManager);
expect(result).toBe(ExtensionUpdateState.UPDATE_AVAILABLE);
});
@@ -224,10 +251,7 @@ describe('git extension helpers', () => {
mockGit.listRemote.mockResolvedValue('same-hash\tHEAD');
mockGit.revparse.mockResolvedValue('same-hash');
const result = await checkForExtensionUpdate(
extension,
new ExtensionEnablementManager(),
);
const result = await checkForExtensionUpdate(extension, extensionManager);
expect(result).toBe(ExtensionUpdateState.UP_TO_DATE);
});
@@ -246,10 +270,7 @@ describe('git extension helpers', () => {
};
mockGit.getRemotes.mockRejectedValue(new Error('git error'));
const result = await checkForExtensionUpdate(
extension,
new ExtensionEnablementManager(),
);
const result = await checkForExtensionUpdate(extension, extensionManager);
expect(result).toBe(ExtensionUpdateState.ERROR);
});
});