chore: fix ide installer

This commit is contained in:
tanzhenxin
2025-08-20 11:25:11 +08:00
parent a0a1d6e253
commit 2fcacb70b9
5 changed files with 18 additions and 101 deletions

View File

@@ -7,6 +7,7 @@
import { import {
Config, Config,
DetectedIde, DetectedIde,
QWEN_CODE_COMPANION_EXTENSION_NAME,
IDEConnectionStatus, IDEConnectionStatus,
getIdeDisplayName, getIdeDisplayName,
getIdeInstaller, getIdeInstaller,
@@ -170,7 +171,7 @@ export const ideCommand = (config: Config | null): SlashCommand | null => {
context.ui.addItem( context.ui.addItem(
{ {
type: 'error', type: 'error',
text: `No installer is available for ${ideClient.getDetectedIdeDisplayName()}. Please install the IDE companion manually from its marketplace.`, text: `No installer is available for ${ideClient.getDetectedIdeDisplayName()}. Please install the '${QWEN_CODE_COMPANION_EXTENSION_NAME}' extension manually from the marketplace.`,
}, },
Date.now(), Date.now(),
); );

View File

@@ -0,0 +1,7 @@
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
export const QWEN_CODE_COMPANION_EXTENSION_NAME = 'Qwen Code Companion';

View File

@@ -24,17 +24,14 @@ describe('ide-installer', () => {
expect(installer).toBeInstanceOf(Object); expect(installer).toBeInstanceOf(Object);
}); });
it('should return an OpenVSXInstaller for "vscodium"', () => { it('should return null for "vscodium" (not implemented)', () => {
const installer = getIdeInstaller(DetectedIde.VSCodium); const installer = getIdeInstaller(DetectedIde.VSCodium);
expect(installer).not.toBeNull(); expect(installer).toBeNull();
expect(installer).toBeInstanceOf(Object);
}); });
it('should return a DefaultIDEInstaller for an unknown IDE', () => { it('should return null for an unknown IDE', () => {
const installer = getIdeInstaller('unknown' as DetectedIde); const installer = getIdeInstaller('unknown' as DetectedIde);
// Assuming DefaultIDEInstaller is the fallback expect(installer).toBeNull();
expect(installer).not.toBeNull();
expect(installer).toBeInstanceOf(Object);
}); });
}); });
@@ -67,44 +64,4 @@ describe('ide-installer', () => {
}); });
}); });
}); });
describe('OpenVSXInstaller', () => {
let installer: IdeInstaller;
beforeEach(() => {
installer = getIdeInstaller(DetectedIde.VSCodium)!;
});
afterEach(() => {
vi.restoreAllMocks();
});
describe('install', () => {
it('should call execSync with the correct command and return success', async () => {
const execSyncSpy = vi
.spyOn(child_process, 'execSync')
.mockImplementation(() => '');
const result = await installer.install();
expect(execSyncSpy).toHaveBeenCalledWith(
'npx ovsx get qwenlm.qwen-code-vscode-ide-companion',
{ stdio: 'pipe' },
);
expect(result.success).toBe(true);
expect(result.message).toContain(
'VS Code companion extension was installed successfully from OpenVSX',
);
});
it('should return a failure message on failed installation', async () => {
vi.spyOn(child_process, 'execSync').mockImplementation(() => {
throw new Error('Command failed');
});
const result = await installer.install();
expect(result.success).toBe(false);
expect(result.message).toContain(
'Failed to install VS Code companion extension from OpenVSX',
);
});
});
});
}); });

View File

@@ -6,15 +6,13 @@
import * as child_process from 'child_process'; import * as child_process from 'child_process';
import * as process from 'process'; import * as process from 'process';
import { glob } from 'glob';
import * as path from 'path'; import * as path from 'path';
import * as fs from 'fs'; import * as fs from 'fs';
import * as os from 'os'; import * as os from 'os';
import { fileURLToPath } from 'url';
import { DetectedIde } from './detect-ide.js'; import { DetectedIde } from './detect-ide.js';
import { QWEN_CODE_COMPANION_EXTENSION_NAME } from './constants.js';
const VSCODE_COMMAND = process.platform === 'win32' ? 'code.cmd' : 'code'; const VSCODE_COMMAND = process.platform === 'win32' ? 'code.cmd' : 'code';
const VSCODE_COMPANION_EXTENSION_FOLDER = 'vscode-ide-companion';
export interface IdeInstaller { export interface IdeInstaller {
install(): Promise<InstallResult>; install(): Promise<InstallResult>;
@@ -103,34 +101,7 @@ class VsCodeInstaller implements IdeInstaller {
}; };
} }
const bundleDir = path.dirname(fileURLToPath(import.meta.url)); const command = `"${commandPath}" --install-extension qwenlm.qwen-code-vscode-ide-companion --force`;
// The VSIX file is copied to the bundle directory as part of the build.
let vsixFiles = glob.sync(path.join(bundleDir, '*.vsix'));
if (vsixFiles.length === 0) {
// If the VSIX file is not in the bundle, it might be a dev
// environment running with `npm start`. Look for it in the original
// package location, relative to the bundle dir.
const devPath = path.join(
bundleDir, // .../packages/core/dist/src/ide
'..', // .../packages/core/dist/src
'..', // .../packages/core/dist
'..', // .../packages/core
'..', // .../packages
VSCODE_COMPANION_EXTENSION_FOLDER,
'*.vsix',
);
vsixFiles = glob.sync(devPath);
}
if (vsixFiles.length === 0) {
return {
success: false,
message:
'Could not find the required VS Code companion extension. Please file a bug via /bug.',
};
}
const vsixPath = vsixFiles[0];
const command = `"${commandPath}" --install-extension "${vsixPath}" --force`;
try { try {
child_process.execSync(command, { stdio: 'pipe' }); child_process.execSync(command, { stdio: 'pipe' });
return { return {
@@ -141,27 +112,7 @@ class VsCodeInstaller implements IdeInstaller {
} catch (_error) { } catch (_error) {
return { return {
success: false, success: false,
message: `Failed to install VS Code companion extension. Please try installing it manually from the VS Code marketplace.`, message: `Failed to install VS Code companion extension. Please try installing '${QWEN_CODE_COMPANION_EXTENSION_NAME}' manually from the VS Code extension marketplace.`,
};
}
}
}
class OpenVSXInstaller implements IdeInstaller {
async install(): Promise<InstallResult> {
// TODO: Use the correct extension path.
const command = `npx ovsx get qwenlm.qwen-code-vscode-ide-companion`;
try {
child_process.execSync(command, { stdio: 'pipe' });
return {
success: true,
message:
'VS Code companion extension was installed successfully from OpenVSX. Please restart your terminal to complete the setup.',
};
} catch (_error) {
return {
success: false,
message: `Failed to install VS Code companion extension from OpenVSX. Please try installing it manually.`,
}; };
} }
} }
@@ -172,6 +123,6 @@ export function getIdeInstaller(ide: DetectedIde): IdeInstaller | null {
case DetectedIde.VSCode: case DetectedIde.VSCode:
return new VsCodeInstaller(); return new VsCodeInstaller();
default: default:
return new OpenVSXInstaller(); return null;
} }
} }

View File

@@ -52,6 +52,7 @@ export * from './ide/ide-client.js';
export * from './ide/ideContext.js'; export * from './ide/ideContext.js';
export * from './ide/ide-installer.js'; export * from './ide/ide-installer.js';
export { getIdeDisplayName, DetectedIde } from './ide/detect-ide.js'; export { getIdeDisplayName, DetectedIde } from './ide/detect-ide.js';
export * from './ide/constants.js';
// Export Shell Execution Service // Export Shell Execution Service
export * from './services/shellExecutionService.js'; export * from './services/shellExecutionService.js';