Skip to content

Commit c1c838a

Browse files
committed
fix up merge errors
1 parent 98ddffa commit c1c838a

File tree

7 files changed

+56
-162
lines changed

7 files changed

+56
-162
lines changed

packages/cli/src/commands/extensions/update.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ import {
1313
updateAllUpdatableExtensions,
1414
type ExtensionUpdateInfo,
1515
checkForAllExtensionUpdates,
16-
checkForExtensionUpdate,
1716
updateExtension,
1817
} from '../../config/extensions/update.js';
18+
import { checkForExtensionUpdate } from '../../config/extensions/github.js';
1919
import { getErrorMessage } from '../../utils/errors.js';
2020
import { ExtensionUpdateState } from '../../ui/state/extensions.js';
2121

@@ -66,7 +66,13 @@ export async function handleUpdate(args: UpdateArgs) {
6666
return;
6767
}
6868
let updateState: ExtensionUpdateState | undefined;
69-
await checkForExtensionUpdate(extension, (newState) => {
69+
if (!extension.installMetadata) {
70+
console.log(
71+
`Unable to install extension "${args.name}" due to missing install metadata`,
72+
);
73+
return;
74+
}
75+
await checkForExtensionUpdate(extension.installMetadata, (newState) => {
7076
updateState = newState;
7177
});
7278
if (updateState !== ExtensionUpdateState.UPDATE_AVAILABLE) {

packages/cli/src/config/extensions/github.test.ts

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,11 @@ describe('git extension helpers', () => {
125125
type: 'local',
126126
source: '',
127127
};
128-
const result = await checkForExtensionUpdate(installMetadata);
128+
let result: ExtensionUpdateState | undefined = undefined;
129+
await checkForExtensionUpdate(
130+
installMetadata,
131+
(newState) => (result = newState),
132+
);
129133
expect(result).toBe(ExtensionUpdateState.NOT_UPDATABLE);
130134
});
131135

@@ -135,7 +139,11 @@ describe('git extension helpers', () => {
135139
source: '',
136140
};
137141
mockGit.getRemotes.mockResolvedValue([]);
138-
const result = await checkForExtensionUpdate(installMetadata);
142+
let result: ExtensionUpdateState | undefined = undefined;
143+
await checkForExtensionUpdate(
144+
installMetadata,
145+
(newState) => (result = newState),
146+
);
139147
expect(result).toBe(ExtensionUpdateState.ERROR);
140148
});
141149

@@ -150,7 +158,11 @@ describe('git extension helpers', () => {
150158
mockGit.listRemote.mockResolvedValue('remote-hash\tHEAD');
151159
mockGit.revparse.mockResolvedValue('local-hash');
152160

153-
const result = await checkForExtensionUpdate(installMetadata);
161+
let result: ExtensionUpdateState | undefined = undefined;
162+
await checkForExtensionUpdate(
163+
installMetadata,
164+
(newState) => (result = newState),
165+
);
154166
expect(result).toBe(ExtensionUpdateState.UPDATE_AVAILABLE);
155167
});
156168

@@ -165,7 +177,11 @@ describe('git extension helpers', () => {
165177
mockGit.listRemote.mockResolvedValue('same-hash\tHEAD');
166178
mockGit.revparse.mockResolvedValue('same-hash');
167179

168-
const result = await checkForExtensionUpdate(installMetadata);
180+
let result: ExtensionUpdateState | undefined = undefined;
181+
await checkForExtensionUpdate(
182+
installMetadata,
183+
(newState) => (result = newState),
184+
);
169185
expect(result).toBe(ExtensionUpdateState.UP_TO_DATE);
170186
});
171187

@@ -175,7 +191,12 @@ describe('git extension helpers', () => {
175191
source: '/ext',
176192
};
177193
mockGit.getRemotes.mockRejectedValue(new Error('git error'));
178-
const result = await checkForExtensionUpdate(installMetadata);
194+
195+
let result: ExtensionUpdateState | undefined = undefined;
196+
await checkForExtensionUpdate(
197+
installMetadata,
198+
(newState) => (result = newState),
199+
);
179200
expect(result).toBe(ExtensionUpdateState.ERROR);
180201
});
181202
});

packages/cli/src/config/extensions/update.test.ts

Lines changed: 7 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ import {
1515
loadExtension,
1616
} from '../extension.js';
1717
import { checkForAllExtensionUpdates, updateExtension } from './update.js';
18-
import { checkForExtensionUpdate } from './github.js';
19-
import { GEMINI_DIR, type GeminiCLIExtension } from '@google/gemini-cli-core';
18+
import { GEMINI_DIR } from '@google/gemini-cli-core';
2019
import { isWorkspaceTrusted } from '../trustedFolders.js';
2120
import { ExtensionUpdateState } from '../../ui/state/extensions.js';
2221
import { createExtension } from '../../test-utils/createExtension.js';
@@ -130,7 +129,12 @@ describe('update tests', () => {
130129
});
131130
mockGit.getRemotes.mockResolvedValue([{ name: 'origin' }]);
132131
const extension = annotateActiveExtensions(
133-
[loadExtension(targetExtDir)!],
132+
[
133+
loadExtension({
134+
extensionDir: targetExtDir,
135+
workspaceDir: tempWorkspaceDir,
136+
})!,
137+
],
134138
[],
135139
process.cwd(),
136140
)[0];
@@ -409,150 +413,4 @@ describe('update tests', () => {
409413
expect(result).toBe(ExtensionUpdateState.ERROR);
410414
});
411415
});
412-
413-
describe('checkForExtensionUpdate', () => {
414-
it('should return UpdateAvailable for a git extension with updates', async () => {
415-
const extensionDir = createExtension({
416-
extensionsDir: userExtensionsDir,
417-
name: 'test-extension',
418-
version: '1.0.0',
419-
installMetadata: {
420-
source: 'https://some.git/repo',
421-
type: 'git',
422-
},
423-
});
424-
const extension = annotateActiveExtensions(
425-
[
426-
loadExtension({
427-
extensionDir,
428-
workspaceDir: tempWorkspaceDir,
429-
})!,
430-
],
431-
[],
432-
process.cwd(),
433-
)[0];
434-
435-
mockGit.getRemotes.mockResolvedValue([
436-
{ name: 'origin', refs: { fetch: 'https://some.git/repo' } },
437-
]);
438-
mockGit.listRemote.mockResolvedValue('remoteHash HEAD');
439-
mockGit.revparse.mockResolvedValue('localHash');
440-
441-
let state: ExtensionUpdateState | undefined = undefined;
442-
await checkForExtensionUpdate(
443-
extension,
444-
(newState) => (state = newState),
445-
);
446-
expect(state).toBe(ExtensionUpdateState.UPDATE_AVAILABLE);
447-
});
448-
449-
it('should return UpToDate for a git extension with no updates', async () => {
450-
const extensionDir = createExtension({
451-
extensionsDir: userExtensionsDir,
452-
name: 'test-extension',
453-
version: '1.0.0',
454-
installMetadata: {
455-
source: 'https://some.git/repo',
456-
type: 'git',
457-
},
458-
});
459-
const extension = annotateActiveExtensions(
460-
[
461-
loadExtension({
462-
extensionDir,
463-
workspaceDir: tempWorkspaceDir,
464-
})!,
465-
],
466-
[],
467-
process.cwd(),
468-
)[0];
469-
470-
mockGit.getRemotes.mockResolvedValue([
471-
{ name: 'origin', refs: { fetch: 'https://some.git/repo' } },
472-
]);
473-
mockGit.listRemote.mockResolvedValue('sameHash HEAD');
474-
mockGit.revparse.mockResolvedValue('sameHash');
475-
476-
let state: ExtensionUpdateState | undefined = undefined;
477-
await checkForExtensionUpdate(
478-
extension,
479-
(newState) => (state = newState),
480-
);
481-
expect(state).toBe(ExtensionUpdateState.UP_TO_DATE);
482-
});
483-
484-
it('should return NotUpdatable for a non-git extension', async () => {
485-
const extensionDir = createExtension({
486-
extensionsDir: userExtensionsDir,
487-
name: 'local-extension',
488-
version: '1.0.0',
489-
});
490-
const extension = annotateActiveExtensions(
491-
[
492-
loadExtension({
493-
extensionDir,
494-
workspaceDir: tempWorkspaceDir,
495-
})!,
496-
],
497-
[],
498-
process.cwd(),
499-
)[0];
500-
501-
let state: ExtensionUpdateState | undefined = undefined;
502-
await checkForExtensionUpdate(
503-
extension,
504-
(newState) => (state = newState),
505-
);
506-
expect(state).toBe(ExtensionUpdateState.NOT_UPDATABLE);
507-
});
508-
509-
it('should return Error when git check fails', async () => {
510-
const extensionDir = createExtension({
511-
extensionsDir: userExtensionsDir,
512-
name: 'error-extension',
513-
version: '1.0.0',
514-
installMetadata: {
515-
source: 'https://some.git/repo',
516-
type: 'git',
517-
},
518-
});
519-
const extension = annotateActiveExtensions(
520-
[
521-
loadExtension({
522-
extensionDir,
523-
workspaceDir: tempWorkspaceDir,
524-
})!,
525-
],
526-
[],
527-
process.cwd(),
528-
)[0];
529-
530-
mockGit.getRemotes.mockRejectedValue(new Error('Git error'));
531-
532-
let state: ExtensionUpdateState | undefined = undefined;
533-
await checkForExtensionUpdate(
534-
extension,
535-
(newState) => (state = newState),
536-
);
537-
expect(state).toBe(ExtensionUpdateState.ERROR);
538-
});
539-
540-
it('should set state to ERROR when no git remotes are found', async () => {
541-
const extension = {
542-
name: 'test-extension',
543-
type: 'git',
544-
};
545-
const setExtensionUpdateState = vi.fn();
546-
mockGit.getRemotes.mockResolvedValue([]);
547-
548-
await checkForExtensionUpdate(
549-
extension as GeminiCLIExtension,
550-
setExtensionUpdateState,
551-
);
552-
553-
expect(setExtensionUpdateState).toHaveBeenCalledWith(
554-
ExtensionUpdateState.ERROR,
555-
);
556-
});
557-
});
558416
});

packages/cli/src/test-utils/createExtension.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ import * as path from 'node:path';
99
import {
1010
EXTENSIONS_CONFIG_FILENAME,
1111
INSTALL_METADATA_FILENAME,
12-
type ExtensionInstallMetadata,
1312
} from '../config/extension.js';
14-
import { type MCPServerConfig } from '@google/gemini-cli-core';
13+
import {
14+
type MCPServerConfig,
15+
type ExtensionInstallMetadata,
16+
} from '@google/gemini-cli-core';
1517

1618
export function createExtension({
1719
extensionsDir = 'extensions-dir',

packages/cli/src/ui/hooks/useExtensionUpdates.test.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,14 @@ describe('useExtensionUpdates', () => {
115115
{
116116
name: 'test-extension',
117117
type: 'git',
118-
autoUpdate: false,
118+
version: '1.0.0',
119+
path: '/some/path',
120+
isActive: true,
121+
installMetadata: {
122+
type: 'git',
123+
source: 'https://some/repo',
124+
autoUpdate: false,
125+
},
119126
},
120127
];
121128
const addItem = vi.fn();
@@ -159,7 +166,7 @@ describe('useExtensionUpdates', () => {
159166
},
160167
});
161168
const extension = annotateActiveExtensions(
162-
[loadExtension(extensionDir)!],
169+
[loadExtension({ extensionDir, workspaceDir: tempHomeDir })!],
163170
[],
164171
tempHomeDir,
165172
)[0];

packages/cli/src/ui/hooks/useExtensionUpdates.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export const useExtensionUpdates = (
3838
) {
3939
continue;
4040
}
41-
if (extension.autoUpdate) {
41+
if (extension.installMetadata?.autoUpdate) {
4242
updateExtension(extension, cwd, currentState, (newState) => {
4343
setExtensionsUpdateState((prev) => {
4444
const finalState = new Map(prev);

packages/core/src/config/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ export interface ExtensionInstallMetadata {
124124
source: string;
125125
type: 'git' | 'local' | 'link' | 'github-release';
126126
ref?: string;
127-
autoUpdate: boolean;
127+
autoUpdate?: boolean;
128128
}
129129

130130
export interface FileFilteringOptions {

0 commit comments

Comments
 (0)