mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-12 12:54:07 -07:00
fix(core/ide): add Antigravity CLI fallbacks (#22030)
This commit is contained in:
@@ -281,15 +281,105 @@ describe('AntigravityInstaller', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns a failure message if the alias is not set', async () => {
|
it('ignores an unsafe alias and falls back to safe commands', async () => {
|
||||||
|
vi.stubEnv('ANTIGRAVITY_CLI_ALIAS', 'agy;malicious_command');
|
||||||
|
const { installer } = setup();
|
||||||
|
vi.mocked(child_process.execSync).mockImplementationOnce(() => 'agy');
|
||||||
|
|
||||||
|
const result = await installer.install();
|
||||||
|
|
||||||
|
expect(result.success).toBe(true);
|
||||||
|
expect(child_process.execSync).toHaveBeenCalledTimes(1);
|
||||||
|
expect(child_process.execSync).toHaveBeenCalledWith('command -v agy', {
|
||||||
|
stdio: 'ignore',
|
||||||
|
});
|
||||||
|
expect(child_process.spawnSync).toHaveBeenCalledWith(
|
||||||
|
'agy',
|
||||||
|
[
|
||||||
|
'--install-extension',
|
||||||
|
'google.gemini-cli-vscode-ide-companion',
|
||||||
|
'--force',
|
||||||
|
],
|
||||||
|
{ stdio: 'pipe', shell: false },
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('falls back to antigravity when agy is unavailable on linux', async () => {
|
||||||
|
vi.stubEnv('ANTIGRAVITY_CLI_ALIAS', 'agy');
|
||||||
|
const { installer } = setup();
|
||||||
|
vi.mocked(child_process.execSync)
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
throw new Error('Command not found');
|
||||||
|
})
|
||||||
|
.mockImplementationOnce(() => 'antigravity');
|
||||||
|
|
||||||
|
const result = await installer.install();
|
||||||
|
|
||||||
|
expect(result.success).toBe(true);
|
||||||
|
expect(child_process.execSync).toHaveBeenNthCalledWith(
|
||||||
|
1,
|
||||||
|
'command -v agy',
|
||||||
|
{
|
||||||
|
stdio: 'ignore',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
expect(child_process.execSync).toHaveBeenNthCalledWith(
|
||||||
|
2,
|
||||||
|
'command -v antigravity',
|
||||||
|
{ stdio: 'ignore' },
|
||||||
|
);
|
||||||
|
expect(child_process.spawnSync).toHaveBeenCalledWith(
|
||||||
|
'antigravity',
|
||||||
|
[
|
||||||
|
'--install-extension',
|
||||||
|
'google.gemini-cli-vscode-ide-companion',
|
||||||
|
'--force',
|
||||||
|
],
|
||||||
|
{ stdio: 'pipe', shell: false },
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('falls back to antigravity.cmd when agy.cmd is unavailable on windows', async () => {
|
||||||
|
vi.stubEnv('ANTIGRAVITY_CLI_ALIAS', 'agy.cmd');
|
||||||
|
const { installer } = setup({
|
||||||
|
platform: 'win32',
|
||||||
|
});
|
||||||
|
vi.mocked(child_process.execSync)
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
throw new Error('Command not found');
|
||||||
|
})
|
||||||
|
.mockImplementationOnce(
|
||||||
|
() => 'C:\\Program Files\\Antigravity\\bin\\antigravity.cmd',
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await installer.install();
|
||||||
|
|
||||||
|
expect(result.success).toBe(true);
|
||||||
|
expect(child_process.execSync).toHaveBeenNthCalledWith(
|
||||||
|
1,
|
||||||
|
'where.exe agy.cmd',
|
||||||
|
);
|
||||||
|
expect(child_process.execSync).toHaveBeenNthCalledWith(
|
||||||
|
2,
|
||||||
|
'where.exe antigravity.cmd',
|
||||||
|
);
|
||||||
|
expect(child_process.spawnSync).toHaveBeenCalledWith(
|
||||||
|
'C:\\Program Files\\Antigravity\\bin\\antigravity.cmd',
|
||||||
|
[
|
||||||
|
'--install-extension',
|
||||||
|
'google.gemini-cli-vscode-ide-companion',
|
||||||
|
'--force',
|
||||||
|
],
|
||||||
|
{ stdio: 'pipe', shell: true },
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('falls back to default commands if the alias is not set', async () => {
|
||||||
vi.stubEnv('ANTIGRAVITY_CLI_ALIAS', '');
|
vi.stubEnv('ANTIGRAVITY_CLI_ALIAS', '');
|
||||||
const { installer } = setup({});
|
const { installer } = setup({});
|
||||||
const result = await installer.install();
|
const result = await installer.install();
|
||||||
|
|
||||||
expect(result.success).toBe(false);
|
expect(result.success).toBe(true);
|
||||||
expect(result.message).toContain(
|
|
||||||
'ANTIGRAVITY_CLI_ALIAS environment variable not set',
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns a failure message if the command is not found', async () => {
|
it('returns a failure message if the command is not found', async () => {
|
||||||
@@ -302,6 +392,7 @@ describe('AntigravityInstaller', () => {
|
|||||||
const result = await installer.install();
|
const result = await installer.install();
|
||||||
|
|
||||||
expect(result.success).toBe(false);
|
expect(result.success).toBe(false);
|
||||||
expect(result.message).toContain('not-a-command not found');
|
expect(result.message).toContain('Antigravity CLI not found');
|
||||||
|
expect(result.message).toContain('agy, antigravity');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -252,19 +252,36 @@ class AntigravityInstaller implements IdeInstaller {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
async install(): Promise<InstallResult> {
|
async install(): Promise<InstallResult> {
|
||||||
const command = process.env['ANTIGRAVITY_CLI_ALIAS'];
|
const envCommand = process.env['ANTIGRAVITY_CLI_ALIAS'];
|
||||||
if (!command) {
|
const safeCommandPattern = /^[a-zA-Z0-9.\-_/\\]+$/;
|
||||||
return {
|
const sanitizedEnvCommand =
|
||||||
success: false,
|
envCommand && safeCommandPattern.test(envCommand)
|
||||||
message: 'ANTIGRAVITY_CLI_ALIAS environment variable not set.',
|
? envCommand
|
||||||
};
|
: undefined;
|
||||||
|
const fallbackCommands =
|
||||||
|
this.platform === 'win32'
|
||||||
|
? ['agy.cmd', 'antigravity.cmd']
|
||||||
|
: ['agy', 'antigravity'];
|
||||||
|
const commands = [
|
||||||
|
...(sanitizedEnvCommand ? [sanitizedEnvCommand] : []),
|
||||||
|
...fallbackCommands,
|
||||||
|
].filter(
|
||||||
|
(command, index, allCommands) => allCommands.indexOf(command) === index,
|
||||||
|
);
|
||||||
|
|
||||||
|
let commandPath: string | null = null;
|
||||||
|
for (const command of commands) {
|
||||||
|
commandPath = await findCommand(command, this.platform);
|
||||||
|
if (commandPath) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const commandPath = await findCommand(command, this.platform);
|
|
||||||
if (!commandPath) {
|
if (!commandPath) {
|
||||||
|
const supportedCommands = fallbackCommands.join(', ');
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
message: `${command} not found. Please ensure it is in your system's PATH.`,
|
message: `Antigravity CLI not found. Please ensure one of these commands is in your system's PATH: ${supportedCommands}.`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user