@google/gemini-cli 0.6.0-preview.6 → 0.6.0-preview.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +2 -2
- package/dist/src/commands/extensions/disable.d.ts +1 -2
- package/dist/src/commands/extensions/disable.js +17 -3
- package/dist/src/commands/extensions/disable.js.map +1 -1
- package/dist/src/commands/extensions/enable.d.ts +1 -2
- package/dist/src/commands/extensions/enable.js +17 -4
- package/dist/src/commands/extensions/enable.js.map +1 -1
- package/dist/src/commands/extensions/install.d.ts +1 -0
- package/dist/src/commands/extensions/install.js +10 -2
- package/dist/src/commands/extensions/install.js.map +1 -1
- package/dist/src/commands/extensions/install.test.js +5 -1
- package/dist/src/commands/extensions/install.test.js.map +1 -1
- package/dist/src/commands/extensions/link.js +1 -1
- package/dist/src/commands/extensions/link.js.map +1 -1
- package/dist/src/commands/extensions/uninstall.js +1 -1
- package/dist/src/commands/extensions/uninstall.js.map +1 -1
- package/dist/src/commands/extensions/update.js +38 -17
- package/dist/src/commands/extensions/update.js.map +1 -1
- package/dist/src/config/extension.d.ts +5 -18
- package/dist/src/config/extension.js +93 -201
- package/dist/src/config/extension.js.map +1 -1
- package/dist/src/config/extensions/extensionEnablement.d.ts +14 -0
- package/dist/src/config/extensions/extensionEnablement.js +81 -33
- package/dist/src/config/extensions/extensionEnablement.js.map +1 -1
- package/dist/src/config/extensions/extensionEnablement.test.js +164 -19
- package/dist/src/config/extensions/extensionEnablement.test.js.map +1 -1
- package/dist/src/config/extensions/github.d.ts +29 -0
- package/dist/src/config/extensions/github.js +314 -0
- package/dist/src/config/extensions/github.js.map +1 -0
- package/dist/src/config/extensions/github.test.d.ts +6 -0
- package/dist/src/config/extensions/github.test.js +267 -0
- package/dist/src/config/extensions/github.test.js.map +1 -0
- package/dist/src/config/extensions/update.d.ts +20 -0
- package/dist/src/config/extensions/update.js +94 -0
- package/dist/src/config/extensions/update.js.map +1 -0
- package/dist/src/config/extensions/update.test.d.ts +6 -0
- package/dist/src/config/extensions/update.test.js +324 -0
- package/dist/src/config/extensions/update.test.js.map +1 -0
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/test-utils/createExtension.d.ts +15 -0
- package/dist/src/test-utils/createExtension.js +25 -0
- package/dist/src/test-utils/createExtension.js.map +1 -0
- package/dist/src/test-utils/mockCommandContext.js +2 -0
- package/dist/src/test-utils/mockCommandContext.js.map +1 -1
- package/dist/src/ui/AppContainer.js +3 -6
- package/dist/src/ui/AppContainer.js.map +1 -1
- package/dist/src/ui/commands/extensionsCommand.js +22 -6
- package/dist/src/ui/commands/extensionsCommand.js.map +1 -1
- package/dist/src/ui/commands/types.d.ts +2 -2
- package/dist/src/ui/hooks/slashCommandProcessor.d.ts +2 -1
- package/dist/src/ui/hooks/slashCommandProcessor.js +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/useExtensionUpdates.d.ts +12 -0
- package/dist/src/ui/hooks/useExtensionUpdates.js +64 -0
- package/dist/src/ui/hooks/useExtensionUpdates.js.map +1 -0
- package/dist/src/ui/hooks/useExtensionUpdates.test.d.ts +6 -0
- package/dist/src/ui/hooks/useExtensionUpdates.test.js +162 -0
- package/dist/src/ui/hooks/useExtensionUpdates.test.js.map +1 -0
- package/dist/src/ui/state/extensions.d.ts +2 -1
- package/dist/src/ui/state/extensions.js +1 -0
- package/dist/src/ui/state/extensions.js.map +1 -1
- package/dist/src/zed-integration/schema.d.ts +22 -22
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { simpleGit } from 'simple-git';
|
|
7
|
+
import { getErrorMessage } from '../../utils/errors.js';
|
|
8
|
+
import { ExtensionUpdateState } from '../../ui/state/extensions.js';
|
|
9
|
+
import * as os from 'node:os';
|
|
10
|
+
import * as https from 'node:https';
|
|
11
|
+
import * as fs from 'node:fs';
|
|
12
|
+
import * as path from 'node:path';
|
|
13
|
+
import { execSync } from 'node:child_process';
|
|
14
|
+
import { loadExtension } from '../extension.js';
|
|
15
|
+
import { quote } from 'shell-quote';
|
|
16
|
+
function getGitHubToken() {
|
|
17
|
+
return process.env['GITHUB_TOKEN'];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Clones a Git repository to a specified local path.
|
|
21
|
+
* @param installMetadata The metadata for the extension to install.
|
|
22
|
+
* @param destination The destination path to clone the repository to.
|
|
23
|
+
*/
|
|
24
|
+
export async function cloneFromGit(installMetadata, destination) {
|
|
25
|
+
try {
|
|
26
|
+
const git = simpleGit(destination);
|
|
27
|
+
let sourceUrl = installMetadata.source;
|
|
28
|
+
const token = getGitHubToken();
|
|
29
|
+
if (token) {
|
|
30
|
+
try {
|
|
31
|
+
const parsedUrl = new URL(sourceUrl);
|
|
32
|
+
if (parsedUrl.protocol === 'https:' &&
|
|
33
|
+
parsedUrl.hostname === 'github.com') {
|
|
34
|
+
if (!parsedUrl.username) {
|
|
35
|
+
parsedUrl.username = token;
|
|
36
|
+
}
|
|
37
|
+
sourceUrl = parsedUrl.toString();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// If source is not a valid URL, we don't inject the token.
|
|
42
|
+
// We let git handle the source as is.
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
await git.clone(sourceUrl, './', ['--depth', '1']);
|
|
46
|
+
const remotes = await git.getRemotes(true);
|
|
47
|
+
if (remotes.length === 0) {
|
|
48
|
+
throw new Error(`Unable to find any remotes for repo ${installMetadata.source}`);
|
|
49
|
+
}
|
|
50
|
+
const refToFetch = installMetadata.ref || 'HEAD';
|
|
51
|
+
await git.fetch(remotes[0].name, refToFetch);
|
|
52
|
+
// After fetching, checkout FETCH_HEAD to get the content of the fetched ref.
|
|
53
|
+
// This results in a detached HEAD state, which is fine for this purpose.
|
|
54
|
+
await git.checkout('FETCH_HEAD');
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
throw new Error(`Failed to clone Git repository from ${installMetadata.source}`, {
|
|
58
|
+
cause: error,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export function parseGitHubRepoForReleases(source) {
|
|
63
|
+
// Default to a github repo path, so `source` can be just an org/repo
|
|
64
|
+
const parsedUrl = URL.parse(source, 'https://github.com');
|
|
65
|
+
// The pathname should be "/owner/repo".
|
|
66
|
+
const parts = parsedUrl?.pathname.substring(1).split('/');
|
|
67
|
+
if (parts?.length !== 2) {
|
|
68
|
+
throw new Error(`Invalid GitHub repository source: ${source}. Expected "owner/repo" or a github repo uri.`);
|
|
69
|
+
}
|
|
70
|
+
const owner = parts[0];
|
|
71
|
+
const repo = parts[1].replace('.git', '');
|
|
72
|
+
if (owner.startsWith('git@github.com')) {
|
|
73
|
+
throw new Error(`GitHub release-based extensions are not supported for SSH. You must use an HTTPS URI with a personal access token to download releases from private repositories. You can set your personal access token in the GITHUB_TOKEN environment variable and install the extension via SSH.`);
|
|
74
|
+
}
|
|
75
|
+
return { owner, repo };
|
|
76
|
+
}
|
|
77
|
+
async function fetchReleaseFromGithub(owner, repo, ref) {
|
|
78
|
+
const endpoint = ref ? `releases/tags/${ref}` : 'releases/latest';
|
|
79
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/${endpoint}`;
|
|
80
|
+
return await fetchJson(url);
|
|
81
|
+
}
|
|
82
|
+
export async function checkForExtensionUpdate(extension, setExtensionUpdateState, cwd = process.cwd()) {
|
|
83
|
+
setExtensionUpdateState(ExtensionUpdateState.CHECKING_FOR_UPDATES);
|
|
84
|
+
const installMetadata = extension.installMetadata;
|
|
85
|
+
if (installMetadata?.type === 'local') {
|
|
86
|
+
const newExtension = loadExtension({
|
|
87
|
+
extensionDir: installMetadata.source,
|
|
88
|
+
workspaceDir: cwd,
|
|
89
|
+
});
|
|
90
|
+
if (!newExtension) {
|
|
91
|
+
console.error(`Failed to check for update for local extension "${extension.name}". Could not load extension from source path: ${installMetadata.source}`);
|
|
92
|
+
setExtensionUpdateState(ExtensionUpdateState.ERROR);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (newExtension.config.version !== extension.version) {
|
|
96
|
+
setExtensionUpdateState(ExtensionUpdateState.UPDATE_AVAILABLE);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
setExtensionUpdateState(ExtensionUpdateState.UP_TO_DATE);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (!installMetadata ||
|
|
103
|
+
(installMetadata.type !== 'git' &&
|
|
104
|
+
installMetadata.type !== 'github-release')) {
|
|
105
|
+
setExtensionUpdateState(ExtensionUpdateState.NOT_UPDATABLE);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
if (installMetadata.type === 'git') {
|
|
110
|
+
const git = simpleGit(extension.path);
|
|
111
|
+
const remotes = await git.getRemotes(true);
|
|
112
|
+
if (remotes.length === 0) {
|
|
113
|
+
console.error('No git remotes found.');
|
|
114
|
+
setExtensionUpdateState(ExtensionUpdateState.ERROR);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const remoteUrl = remotes[0].refs.fetch;
|
|
118
|
+
if (!remoteUrl) {
|
|
119
|
+
console.error(`No fetch URL found for git remote ${remotes[0].name}.`);
|
|
120
|
+
setExtensionUpdateState(ExtensionUpdateState.ERROR);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
// Determine the ref to check on the remote.
|
|
124
|
+
const refToCheck = installMetadata.ref || 'HEAD';
|
|
125
|
+
const lsRemoteOutput = await git.listRemote([remoteUrl, refToCheck]);
|
|
126
|
+
if (typeof lsRemoteOutput !== 'string' || lsRemoteOutput.trim() === '') {
|
|
127
|
+
console.error(`Git ref ${refToCheck} not found.`);
|
|
128
|
+
setExtensionUpdateState(ExtensionUpdateState.ERROR);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const remoteHash = lsRemoteOutput.split('\t')[0];
|
|
132
|
+
const localHash = await git.revparse(['HEAD']);
|
|
133
|
+
if (!remoteHash) {
|
|
134
|
+
console.error(`Unable to parse hash from git ls-remote output "${lsRemoteOutput}"`);
|
|
135
|
+
setExtensionUpdateState(ExtensionUpdateState.ERROR);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (remoteHash === localHash) {
|
|
139
|
+
setExtensionUpdateState(ExtensionUpdateState.UP_TO_DATE);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
setExtensionUpdateState(ExtensionUpdateState.UPDATE_AVAILABLE);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
const { source, releaseTag } = installMetadata;
|
|
147
|
+
if (!source) {
|
|
148
|
+
console.error(`No "source" provided for extension.`);
|
|
149
|
+
setExtensionUpdateState(ExtensionUpdateState.ERROR);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const { owner, repo } = parseGitHubRepoForReleases(source);
|
|
153
|
+
const releaseData = await fetchReleaseFromGithub(owner, repo, installMetadata.ref);
|
|
154
|
+
if (releaseData.tag_name !== releaseTag) {
|
|
155
|
+
setExtensionUpdateState(ExtensionUpdateState.UPDATE_AVAILABLE);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
setExtensionUpdateState(ExtensionUpdateState.UP_TO_DATE);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
console.error(`Failed to check for updates for extension "${installMetadata.source}": ${getErrorMessage(error)}`);
|
|
164
|
+
setExtensionUpdateState(ExtensionUpdateState.ERROR);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
export async function downloadFromGitHubRelease(installMetadata, destination) {
|
|
169
|
+
const { source, ref } = installMetadata;
|
|
170
|
+
const { owner, repo } = parseGitHubRepoForReleases(source);
|
|
171
|
+
try {
|
|
172
|
+
const releaseData = await fetchReleaseFromGithub(owner, repo, ref);
|
|
173
|
+
if (!releaseData) {
|
|
174
|
+
throw new Error(`No release data found for ${owner}/${repo} at tag ${ref}`);
|
|
175
|
+
}
|
|
176
|
+
const asset = findReleaseAsset(releaseData.assets);
|
|
177
|
+
let archiveUrl;
|
|
178
|
+
let isTar = false;
|
|
179
|
+
let isZip = false;
|
|
180
|
+
if (asset) {
|
|
181
|
+
archiveUrl = asset.browser_download_url;
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
if (releaseData.tarball_url) {
|
|
185
|
+
archiveUrl = releaseData.tarball_url;
|
|
186
|
+
isTar = true;
|
|
187
|
+
}
|
|
188
|
+
else if (releaseData.zipball_url) {
|
|
189
|
+
archiveUrl = releaseData.zipball_url;
|
|
190
|
+
isZip = true;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (!archiveUrl) {
|
|
194
|
+
throw new Error(`No assets found for release with tag ${releaseData.tag_name}`);
|
|
195
|
+
}
|
|
196
|
+
let downloadedAssetPath = path.join(destination, path.basename(new URL(archiveUrl).pathname));
|
|
197
|
+
if (isTar && !downloadedAssetPath.endsWith('.tar.gz')) {
|
|
198
|
+
downloadedAssetPath += '.tar.gz';
|
|
199
|
+
}
|
|
200
|
+
else if (isZip && !downloadedAssetPath.endsWith('.zip')) {
|
|
201
|
+
downloadedAssetPath += '.zip';
|
|
202
|
+
}
|
|
203
|
+
await downloadFile(archiveUrl, downloadedAssetPath);
|
|
204
|
+
extractFile(downloadedAssetPath, destination);
|
|
205
|
+
const files = await fs.promises.readdir(destination);
|
|
206
|
+
const extractedDirName = files.find((file) => {
|
|
207
|
+
const filePath = path.join(destination, file);
|
|
208
|
+
return fs.statSync(filePath).isDirectory();
|
|
209
|
+
});
|
|
210
|
+
if (extractedDirName) {
|
|
211
|
+
const extractedDirPath = path.join(destination, extractedDirName);
|
|
212
|
+
const extractedDirFiles = await fs.promises.readdir(extractedDirPath);
|
|
213
|
+
for (const file of extractedDirFiles) {
|
|
214
|
+
await fs.promises.rename(path.join(extractedDirPath, file), path.join(destination, file));
|
|
215
|
+
}
|
|
216
|
+
await fs.promises.rmdir(extractedDirPath);
|
|
217
|
+
}
|
|
218
|
+
await fs.promises.unlink(downloadedAssetPath);
|
|
219
|
+
return {
|
|
220
|
+
tagName: releaseData.tag_name,
|
|
221
|
+
type: 'github-release',
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
throw new Error(`Failed to download release from ${installMetadata.source}: ${getErrorMessage(error)}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
export function findReleaseAsset(assets) {
|
|
229
|
+
const platform = os.platform();
|
|
230
|
+
const arch = os.arch();
|
|
231
|
+
const platformArchPrefix = `${platform}.${arch}.`;
|
|
232
|
+
const platformPrefix = `${platform}.`;
|
|
233
|
+
// Check for platform + architecture specific asset
|
|
234
|
+
const platformArchAsset = assets.find((asset) => asset.name.toLowerCase().startsWith(platformArchPrefix));
|
|
235
|
+
if (platformArchAsset) {
|
|
236
|
+
return platformArchAsset;
|
|
237
|
+
}
|
|
238
|
+
// Check for platform specific asset
|
|
239
|
+
const platformAsset = assets.find((asset) => asset.name.toLowerCase().startsWith(platformPrefix));
|
|
240
|
+
if (platformAsset) {
|
|
241
|
+
return platformAsset;
|
|
242
|
+
}
|
|
243
|
+
// Check for generic asset if only one is available
|
|
244
|
+
const genericAsset = assets.find((asset) => !asset.name.toLowerCase().includes('darwin') &&
|
|
245
|
+
!asset.name.toLowerCase().includes('linux') &&
|
|
246
|
+
!asset.name.toLowerCase().includes('win32'));
|
|
247
|
+
if (assets.length === 1) {
|
|
248
|
+
return genericAsset;
|
|
249
|
+
}
|
|
250
|
+
return undefined;
|
|
251
|
+
}
|
|
252
|
+
async function fetchJson(url) {
|
|
253
|
+
const headers = {
|
|
254
|
+
'User-Agent': 'gemini-cli',
|
|
255
|
+
};
|
|
256
|
+
const token = getGitHubToken();
|
|
257
|
+
if (token) {
|
|
258
|
+
headers.Authorization = `token ${token}`;
|
|
259
|
+
}
|
|
260
|
+
return new Promise((resolve, reject) => {
|
|
261
|
+
https
|
|
262
|
+
.get(url, { headers }, (res) => {
|
|
263
|
+
if (res.statusCode !== 200) {
|
|
264
|
+
return reject(new Error(`Request failed with status code ${res.statusCode}`));
|
|
265
|
+
}
|
|
266
|
+
const chunks = [];
|
|
267
|
+
res.on('data', (chunk) => chunks.push(chunk));
|
|
268
|
+
res.on('end', () => {
|
|
269
|
+
const data = Buffer.concat(chunks).toString();
|
|
270
|
+
resolve(JSON.parse(data));
|
|
271
|
+
});
|
|
272
|
+
})
|
|
273
|
+
.on('error', reject);
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
async function downloadFile(url, dest) {
|
|
277
|
+
const headers = {
|
|
278
|
+
'User-agent': 'gemini-cli',
|
|
279
|
+
};
|
|
280
|
+
const token = getGitHubToken();
|
|
281
|
+
if (token) {
|
|
282
|
+
headers.Authorization = `token ${token}`;
|
|
283
|
+
}
|
|
284
|
+
return new Promise((resolve, reject) => {
|
|
285
|
+
https
|
|
286
|
+
.get(url, { headers }, (res) => {
|
|
287
|
+
if (res.statusCode === 302 || res.statusCode === 301) {
|
|
288
|
+
downloadFile(res.headers.location, dest).then(resolve).catch(reject);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
if (res.statusCode !== 200) {
|
|
292
|
+
return reject(new Error(`Request failed with status code ${res.statusCode}`));
|
|
293
|
+
}
|
|
294
|
+
const file = fs.createWriteStream(dest);
|
|
295
|
+
res.pipe(file);
|
|
296
|
+
file.on('finish', () => file.close(resolve));
|
|
297
|
+
})
|
|
298
|
+
.on('error', reject);
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
function extractFile(file, dest) {
|
|
302
|
+
const safeFile = quote([file]);
|
|
303
|
+
const safeDest = quote([dest]);
|
|
304
|
+
if (file.endsWith('.tar.gz')) {
|
|
305
|
+
execSync(`tar -xzf ${safeFile} -C ${safeDest}`);
|
|
306
|
+
}
|
|
307
|
+
else if (file.endsWith('.zip')) {
|
|
308
|
+
execSync(`unzip ${safeFile} -d ${safeDest}`);
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
throw new Error(`Unsupported file extension for extraction: ${file}`);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../../../src/config/extensions/github.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
7
|
+
import { checkForExtensionUpdate, cloneFromGit, findReleaseAsset, parseGitHubRepoForReleases, } from './github.js';
|
|
8
|
+
import { simpleGit } from 'simple-git';
|
|
9
|
+
import { ExtensionUpdateState } from '../../ui/state/extensions.js';
|
|
10
|
+
const mockPlatform = vi.hoisted(() => vi.fn());
|
|
11
|
+
const mockArch = vi.hoisted(() => vi.fn());
|
|
12
|
+
vi.mock('node:os', async (importOriginal) => {
|
|
13
|
+
const actual = await importOriginal();
|
|
14
|
+
return {
|
|
15
|
+
...actual,
|
|
16
|
+
platform: mockPlatform,
|
|
17
|
+
arch: mockArch,
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
vi.mock('simple-git');
|
|
21
|
+
describe('git extension helpers', () => {
|
|
22
|
+
afterEach(() => {
|
|
23
|
+
vi.restoreAllMocks();
|
|
24
|
+
});
|
|
25
|
+
describe('cloneFromGit', () => {
|
|
26
|
+
const mockGit = {
|
|
27
|
+
clone: vi.fn(),
|
|
28
|
+
getRemotes: vi.fn(),
|
|
29
|
+
fetch: vi.fn(),
|
|
30
|
+
checkout: vi.fn(),
|
|
31
|
+
};
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
vi.mocked(simpleGit).mockReturnValue(mockGit);
|
|
34
|
+
});
|
|
35
|
+
it('should clone, fetch and checkout a repo', async () => {
|
|
36
|
+
const installMetadata = {
|
|
37
|
+
source: 'http://my-repo.com',
|
|
38
|
+
ref: 'my-ref',
|
|
39
|
+
type: 'git',
|
|
40
|
+
};
|
|
41
|
+
const destination = '/dest';
|
|
42
|
+
mockGit.getRemotes.mockResolvedValue([
|
|
43
|
+
{ name: 'origin', refs: { fetch: 'http://my-repo.com' } },
|
|
44
|
+
]);
|
|
45
|
+
await cloneFromGit(installMetadata, destination);
|
|
46
|
+
expect(mockGit.clone).toHaveBeenCalledWith('http://my-repo.com', './', [
|
|
47
|
+
'--depth',
|
|
48
|
+
'1',
|
|
49
|
+
]);
|
|
50
|
+
expect(mockGit.getRemotes).toHaveBeenCalledWith(true);
|
|
51
|
+
expect(mockGit.fetch).toHaveBeenCalledWith('origin', 'my-ref');
|
|
52
|
+
expect(mockGit.checkout).toHaveBeenCalledWith('FETCH_HEAD');
|
|
53
|
+
});
|
|
54
|
+
it('should use HEAD if ref is not provided', async () => {
|
|
55
|
+
const installMetadata = {
|
|
56
|
+
source: 'http://my-repo.com',
|
|
57
|
+
type: 'git',
|
|
58
|
+
};
|
|
59
|
+
const destination = '/dest';
|
|
60
|
+
mockGit.getRemotes.mockResolvedValue([
|
|
61
|
+
{ name: 'origin', refs: { fetch: 'http://my-repo.com' } },
|
|
62
|
+
]);
|
|
63
|
+
await cloneFromGit(installMetadata, destination);
|
|
64
|
+
expect(mockGit.fetch).toHaveBeenCalledWith('origin', 'HEAD');
|
|
65
|
+
});
|
|
66
|
+
it('should throw if no remotes are found', async () => {
|
|
67
|
+
const installMetadata = {
|
|
68
|
+
source: 'http://my-repo.com',
|
|
69
|
+
type: 'git',
|
|
70
|
+
};
|
|
71
|
+
const destination = '/dest';
|
|
72
|
+
mockGit.getRemotes.mockResolvedValue([]);
|
|
73
|
+
await expect(cloneFromGit(installMetadata, destination)).rejects.toThrow('Failed to clone Git repository from http://my-repo.com');
|
|
74
|
+
});
|
|
75
|
+
it('should throw on clone error', async () => {
|
|
76
|
+
const installMetadata = {
|
|
77
|
+
source: 'http://my-repo.com',
|
|
78
|
+
type: 'git',
|
|
79
|
+
};
|
|
80
|
+
const destination = '/dest';
|
|
81
|
+
mockGit.clone.mockRejectedValue(new Error('clone failed'));
|
|
82
|
+
await expect(cloneFromGit(installMetadata, destination)).rejects.toThrow('Failed to clone Git repository from http://my-repo.com');
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
describe('checkForExtensionUpdate', () => {
|
|
86
|
+
const mockGit = {
|
|
87
|
+
getRemotes: vi.fn(),
|
|
88
|
+
listRemote: vi.fn(),
|
|
89
|
+
revparse: vi.fn(),
|
|
90
|
+
};
|
|
91
|
+
beforeEach(() => {
|
|
92
|
+
vi.mocked(simpleGit).mockReturnValue(mockGit);
|
|
93
|
+
});
|
|
94
|
+
it('should return NOT_UPDATABLE for non-git extensions', async () => {
|
|
95
|
+
const extension = {
|
|
96
|
+
name: 'test',
|
|
97
|
+
path: '/ext',
|
|
98
|
+
version: '1.0.0',
|
|
99
|
+
isActive: true,
|
|
100
|
+
installMetadata: {
|
|
101
|
+
type: 'link',
|
|
102
|
+
source: '',
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
let result = undefined;
|
|
106
|
+
await checkForExtensionUpdate(extension, (newState) => (result = newState));
|
|
107
|
+
expect(result).toBe(ExtensionUpdateState.NOT_UPDATABLE);
|
|
108
|
+
});
|
|
109
|
+
it('should return ERROR if no remotes found', async () => {
|
|
110
|
+
const extension = {
|
|
111
|
+
name: 'test',
|
|
112
|
+
path: '/ext',
|
|
113
|
+
version: '1.0.0',
|
|
114
|
+
isActive: true,
|
|
115
|
+
installMetadata: {
|
|
116
|
+
type: 'git',
|
|
117
|
+
source: '',
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
mockGit.getRemotes.mockResolvedValue([]);
|
|
121
|
+
let result = undefined;
|
|
122
|
+
await checkForExtensionUpdate(extension, (newState) => (result = newState));
|
|
123
|
+
expect(result).toBe(ExtensionUpdateState.ERROR);
|
|
124
|
+
});
|
|
125
|
+
it('should return UPDATE_AVAILABLE when remote hash is different', async () => {
|
|
126
|
+
const extension = {
|
|
127
|
+
name: 'test',
|
|
128
|
+
path: '/ext',
|
|
129
|
+
version: '1.0.0',
|
|
130
|
+
isActive: true,
|
|
131
|
+
installMetadata: {
|
|
132
|
+
type: 'git',
|
|
133
|
+
source: 'my/ext',
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
mockGit.getRemotes.mockResolvedValue([
|
|
137
|
+
{ name: 'origin', refs: { fetch: 'http://my-repo.com' } },
|
|
138
|
+
]);
|
|
139
|
+
mockGit.listRemote.mockResolvedValue('remote-hash\tHEAD');
|
|
140
|
+
mockGit.revparse.mockResolvedValue('local-hash');
|
|
141
|
+
let result = undefined;
|
|
142
|
+
await checkForExtensionUpdate(extension, (newState) => (result = newState));
|
|
143
|
+
expect(result).toBe(ExtensionUpdateState.UPDATE_AVAILABLE);
|
|
144
|
+
});
|
|
145
|
+
it('should return UP_TO_DATE when remote and local hashes are the same', async () => {
|
|
146
|
+
const extension = {
|
|
147
|
+
name: 'test',
|
|
148
|
+
path: '/ext',
|
|
149
|
+
version: '1.0.0',
|
|
150
|
+
isActive: true,
|
|
151
|
+
installMetadata: {
|
|
152
|
+
type: 'git',
|
|
153
|
+
source: 'my/ext',
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
mockGit.getRemotes.mockResolvedValue([
|
|
157
|
+
{ name: 'origin', refs: { fetch: 'http://my-repo.com' } },
|
|
158
|
+
]);
|
|
159
|
+
mockGit.listRemote.mockResolvedValue('same-hash\tHEAD');
|
|
160
|
+
mockGit.revparse.mockResolvedValue('same-hash');
|
|
161
|
+
let result = undefined;
|
|
162
|
+
await checkForExtensionUpdate(extension, (newState) => (result = newState));
|
|
163
|
+
expect(result).toBe(ExtensionUpdateState.UP_TO_DATE);
|
|
164
|
+
});
|
|
165
|
+
it('should return ERROR on git error', async () => {
|
|
166
|
+
const extension = {
|
|
167
|
+
name: 'test',
|
|
168
|
+
path: '/ext',
|
|
169
|
+
version: '1.0.0',
|
|
170
|
+
isActive: true,
|
|
171
|
+
installMetadata: {
|
|
172
|
+
type: 'git',
|
|
173
|
+
source: 'my/ext',
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
mockGit.getRemotes.mockRejectedValue(new Error('git error'));
|
|
177
|
+
let result = undefined;
|
|
178
|
+
await checkForExtensionUpdate(extension, (newState) => (result = newState));
|
|
179
|
+
expect(result).toBe(ExtensionUpdateState.ERROR);
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
describe('findReleaseAsset', () => {
|
|
183
|
+
const assets = [
|
|
184
|
+
{ name: 'darwin.arm64.extension.tar.gz', browser_download_url: 'url1' },
|
|
185
|
+
{ name: 'darwin.x64.extension.tar.gz', browser_download_url: 'url2' },
|
|
186
|
+
{ name: 'linux.x64.extension.tar.gz', browser_download_url: 'url3' },
|
|
187
|
+
{ name: 'win32.x64.extension.tar.gz', browser_download_url: 'url4' },
|
|
188
|
+
{ name: 'extension-generic.tar.gz', browser_download_url: 'url5' },
|
|
189
|
+
];
|
|
190
|
+
it('should find asset matching platform and architecture', () => {
|
|
191
|
+
mockPlatform.mockReturnValue('darwin');
|
|
192
|
+
mockArch.mockReturnValue('arm64');
|
|
193
|
+
const result = findReleaseAsset(assets);
|
|
194
|
+
expect(result).toEqual(assets[0]);
|
|
195
|
+
});
|
|
196
|
+
it('should find asset matching platform if arch does not match', () => {
|
|
197
|
+
mockPlatform.mockReturnValue('linux');
|
|
198
|
+
mockArch.mockReturnValue('arm64');
|
|
199
|
+
const result = findReleaseAsset(assets);
|
|
200
|
+
expect(result).toEqual(assets[2]);
|
|
201
|
+
});
|
|
202
|
+
it('should return undefined if no matching asset is found', () => {
|
|
203
|
+
mockPlatform.mockReturnValue('sunos');
|
|
204
|
+
mockArch.mockReturnValue('x64');
|
|
205
|
+
const result = findReleaseAsset(assets);
|
|
206
|
+
expect(result).toBeUndefined();
|
|
207
|
+
});
|
|
208
|
+
it('should find generic asset if it is the only one', () => {
|
|
209
|
+
const singleAsset = [
|
|
210
|
+
{ name: 'extension.tar.gz', browser_download_url: 'url' },
|
|
211
|
+
];
|
|
212
|
+
mockPlatform.mockReturnValue('darwin');
|
|
213
|
+
mockArch.mockReturnValue('arm64');
|
|
214
|
+
const result = findReleaseAsset(singleAsset);
|
|
215
|
+
expect(result).toEqual(singleAsset[0]);
|
|
216
|
+
});
|
|
217
|
+
it('should return undefined if multiple generic assets exist', () => {
|
|
218
|
+
const multipleGenericAssets = [
|
|
219
|
+
{ name: 'extension-1.tar.gz', browser_download_url: 'url1' },
|
|
220
|
+
{ name: 'extension-2.tar.gz', browser_download_url: 'url2' },
|
|
221
|
+
];
|
|
222
|
+
mockPlatform.mockReturnValue('darwin');
|
|
223
|
+
mockArch.mockReturnValue('arm64');
|
|
224
|
+
const result = findReleaseAsset(multipleGenericAssets);
|
|
225
|
+
expect(result).toBeUndefined();
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
describe('parseGitHubRepoForReleases', () => {
|
|
229
|
+
it('should parse owner and repo from a full GitHub URL', () => {
|
|
230
|
+
const source = 'https://github.com/owner/repo.git';
|
|
231
|
+
const { owner, repo } = parseGitHubRepoForReleases(source);
|
|
232
|
+
expect(owner).toBe('owner');
|
|
233
|
+
expect(repo).toBe('repo');
|
|
234
|
+
});
|
|
235
|
+
it('should parse owner and repo from a full GitHub UR without .git', () => {
|
|
236
|
+
const source = 'https://github.com/owner/repo';
|
|
237
|
+
const { owner, repo } = parseGitHubRepoForReleases(source);
|
|
238
|
+
expect(owner).toBe('owner');
|
|
239
|
+
expect(repo).toBe('repo');
|
|
240
|
+
});
|
|
241
|
+
it('should fail on a GitHub SSH URL', () => {
|
|
242
|
+
const source = 'git@github.com:owner/repo.git';
|
|
243
|
+
expect(() => parseGitHubRepoForReleases(source)).toThrow('GitHub release-based extensions are not supported for SSH. You must use an HTTPS URI with a personal access token to download releases from private repositories. You can set your personal access token in the GITHUB_TOKEN environment variable and install the extension via SSH.');
|
|
244
|
+
});
|
|
245
|
+
it('should parse owner and repo from a shorthand string', () => {
|
|
246
|
+
const source = 'owner/repo';
|
|
247
|
+
const { owner, repo } = parseGitHubRepoForReleases(source);
|
|
248
|
+
expect(owner).toBe('owner');
|
|
249
|
+
expect(repo).toBe('repo');
|
|
250
|
+
});
|
|
251
|
+
it('should handle .git suffix in repo name', () => {
|
|
252
|
+
const source = 'owner/repo.git';
|
|
253
|
+
const { owner, repo } = parseGitHubRepoForReleases(source);
|
|
254
|
+
expect(owner).toBe('owner');
|
|
255
|
+
expect(repo).toBe('repo');
|
|
256
|
+
});
|
|
257
|
+
it('should throw error for invalid source format', () => {
|
|
258
|
+
const source = 'invalid-format';
|
|
259
|
+
expect(() => parseGitHubRepoForReleases(source)).toThrow('Invalid GitHub repository source: invalid-format. Expected "owner/repo" or a github repo uri.');
|
|
260
|
+
});
|
|
261
|
+
it('should throw error for source with too many parts', () => {
|
|
262
|
+
const source = 'https://github.com/owner/repo/extra';
|
|
263
|
+
expect(() => parseGitHubRepoForReleases(source)).toThrow('Invalid GitHub repository source: https://github.com/owner/repo/extra. Expected "owner/repo" or a github repo uri.');
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
//# sourceMappingURL=github.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.test.js","sourceRoot":"","sources":["../../../../src/config/extensions/github.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import type { GeminiCLIExtension } from '@google/gemini-cli-core';
|
|
7
|
+
import { ExtensionUpdateState } from '../../ui/state/extensions.js';
|
|
8
|
+
import { type Dispatch, type SetStateAction } from 'react';
|
|
9
|
+
export interface ExtensionUpdateInfo {
|
|
10
|
+
name: string;
|
|
11
|
+
originalVersion: string;
|
|
12
|
+
updatedVersion: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function updateExtension(extension: GeminiCLIExtension, cwd: string | undefined, currentState: ExtensionUpdateState, setExtensionUpdateState: (updateState: ExtensionUpdateState) => void): Promise<ExtensionUpdateInfo | undefined>;
|
|
15
|
+
export declare function updateAllUpdatableExtensions(cwd: string | undefined, extensions: GeminiCLIExtension[], extensionsState: Map<string, ExtensionUpdateState>, setExtensionsUpdateState: Dispatch<SetStateAction<Map<string, ExtensionUpdateState>>>): Promise<ExtensionUpdateInfo[]>;
|
|
16
|
+
export interface ExtensionUpdateCheckResult {
|
|
17
|
+
state: ExtensionUpdateState;
|
|
18
|
+
error?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function checkForAllExtensionUpdates(extensions: GeminiCLIExtension[], extensionsUpdateState: Map<string, ExtensionUpdateState>, setExtensionsUpdateState: Dispatch<SetStateAction<Map<string, ExtensionUpdateState>>>, cwd?: string): Promise<Map<string, ExtensionUpdateState>>;
|