Skip to content

Commit a2bc061

Browse files
committed
allow setting default tag while installing extensions
1 parent 01b37c6 commit a2bc061

5 files changed

Lines changed: 40 additions & 31 deletions

File tree

src/vs/code/node/cliProcessMain.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export class Main {
8686
} else if (argv['list-extensions']) {
8787
await this.listExtensions(!!argv['show-versions'], argv['category']);
8888
} else if (argv['install-extension']) {
89-
await this.installExtensions(argv['install-extension'], !!argv['force']);
89+
await this.installExtensions(argv['install-extension'], !!argv['force'], !!argv['default']);
9090
} else if (argv['uninstall-extension']) {
9191
await this.uninstallExtension(argv['uninstall-extension']);
9292
} else if (argv['locate-extension']) {
@@ -126,7 +126,7 @@ export class Main {
126126
extensions.forEach(e => console.log(getId(e.manifest, showVersions)));
127127
}
128128

129-
private async installExtensions(extensions: string[], force: boolean): Promise<void> {
129+
private async installExtensions(extensions: string[], force: boolean, isDefault: boolean): Promise<void> {
130130
const failed: string[] = [];
131131
const installedExtensionsManifests: IExtensionManifest[] = [];
132132
if (extensions.length) {
@@ -135,7 +135,7 @@ export class Main {
135135

136136
for (const extension of extensions) {
137137
try {
138-
const manifest = await this.installExtension(extension, force);
138+
const manifest = await this.installExtension(extension, force, isDefault);
139139
if (manifest) {
140140
installedExtensionsManifests.push(manifest);
141141
}
@@ -150,7 +150,7 @@ export class Main {
150150
return failed.length ? Promise.reject(localize('installation failed', "Failed Installing Extensions: {0}", failed.join(', '))) : Promise.resolve();
151151
}
152152

153-
private async installExtension(extension: string, force: boolean): Promise<IExtensionManifest | null> {
153+
private async installExtension(extension: string, force: boolean, isDefault: boolean): Promise<IExtensionManifest | null> {
154154
if (/\.vsix$/i.test(extension)) {
155155
extension = path.isAbsolute(extension) ? extension : path.join(process.cwd(), extension);
156156

@@ -205,7 +205,7 @@ export class Main {
205205
}
206206
console.log(localize('updateMessage', "Updating the extension '{0}' to the version {1}", id, extension.version));
207207
}
208-
await this.installFromGallery(id, extension);
208+
await this.installFromGallery(id, extension, isDefault);
209209
return manifest;
210210
}));
211211
}
@@ -227,11 +227,11 @@ export class Main {
227227
return true;
228228
}
229229

230-
private async installFromGallery(id: string, extension: IGalleryExtension): Promise<void> {
230+
private async installFromGallery(id: string, extension: IGalleryExtension, isDefault: boolean): Promise<void> {
231231
console.log(localize('installing', "Installing extension '{0}' v{1}...", id, extension.version));
232232

233233
try {
234-
await this.extensionManagementService.installFromGallery(extension);
234+
await this.extensionManagementService.installFromGallery(extension, isDefault);
235235
console.log(localize('successInstall', "Extension '{0}' v{1} was successfully installed.", id, extension.version));
236236
} catch (error) {
237237
if (isPromiseCanceledError(error)) {

src/vs/platform/environment/node/argv.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export interface ParsedArgs {
7272
remote?: string;
7373
'disable-user-env-probe'?: boolean;
7474
'force'?: boolean;
75+
'default'?: boolean;
7576
'force-user-env'?: boolean;
7677
'sync'?: 'on' | 'off';
7778

@@ -187,6 +188,7 @@ export const OPTIONS: OptionDescriptions<Required<ParsedArgs>> = {
187188
'file-chmod': { type: 'boolean' },
188189
'driver-verbose': { type: 'boolean' },
189190
'force': { type: 'boolean' },
191+
'default': { type: 'boolean' },
190192
'trace': { type: 'boolean' },
191193
'trace-category-filter': { type: 'string' },
192194
'trace-options': { type: 'string' },

src/vs/platform/extensionManagement/common/extensionManagement.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ export interface IGalleryMetadata {
9292

9393
export interface ILocalExtension extends IExtension {
9494
readonly manifest: IExtensionManifest;
95+
isDefault: boolean;
9596
publisherId: string | null;
9697
publisherDisplayName: string | null;
9798
readmeUrl: URI | null;
@@ -205,8 +206,8 @@ export interface IExtensionManagementService {
205206
zip(extension: ILocalExtension): Promise<URI>;
206207
unzip(zipLocation: URI): Promise<IExtensionIdentifier>;
207208
getManifest(vsix: URI): Promise<IExtensionManifest>;
208-
install(vsix: URI): Promise<ILocalExtension>;
209-
installFromGallery(extension: IGalleryExtension): Promise<ILocalExtension>;
209+
install(vsix: URI, isDefault?: boolean): Promise<ILocalExtension>;
210+
installFromGallery(extension: IGalleryExtension, isDefault?: boolean): Promise<ILocalExtension>;
210211
uninstall(extension: ILocalExtension, force?: boolean): Promise<void>;
211212
reinstallFromGallery(extension: ILocalExtension): Promise<void>;
212213
getInstalled(type?: ExtensionType): Promise<ILocalExtension[]>;

src/vs/platform/extensionManagement/node/extensionManagementService.ts

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ import { CancellationToken } from 'vs/base/common/cancellation';
4545
import { getManifest } from 'vs/platform/extensionManagement/node/extensionManagementUtil';
4646
import { IExtensionManifest, ExtensionType } from 'vs/platform/extensions/common/extensions';
4747
import { ExtensionsDownloader } from 'vs/platform/extensionManagement/node/extensionDownloader';
48-
import { ExtensionsScanner } from 'vs/platform/extensionManagement/node/extensionsScanner';
48+
import { ExtensionsScanner, IMetadata } from 'vs/platform/extensionManagement/node/extensionsScanner';
4949
import { ExtensionsLifecycle } from 'vs/platform/extensionManagement/node/extensionLifecycle';
5050

5151
const INSTALL_ERROR_UNSET_UNINSTALLED = 'unsetUninstalled';
@@ -57,7 +57,7 @@ const ERROR_UNKNOWN = 'unknown';
5757
interface InstallableExtension {
5858
zipPath: string;
5959
identifierWithVersion: ExtensionIdentifierWithVersion;
60-
metadata: IGalleryMetadata | null;
60+
metadata?: IMetadata;
6161
}
6262

6363
export class ExtensionManagementService extends Disposable implements IExtensionManagementService {
@@ -152,7 +152,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
152152

153153
}
154154

155-
install(vsix: URI): Promise<ILocalExtension> {
155+
install(vsix: URI, isDefault: boolean = false): Promise<ILocalExtension> {
156156
this.logService.trace('ExtensionManagementService#install', vsix.toString());
157157
return createCancelablePromise(token => {
158158
return this.downloadVsix(vsix).then(downloadLocation => {
@@ -192,10 +192,10 @@ export class ExtensionManagementService extends Disposable implements IExtension
192192
.then(() => {
193193
this.logService.info('Installing the extension:', identifier.id);
194194
this._onInstallExtension.fire({ identifier, zipPath });
195-
return this.getMetadata(getGalleryExtensionId(manifest.publisher, manifest.name))
195+
return this.getGalleryMetadata(getGalleryExtensionId(manifest.publisher, manifest.name))
196196
.then(
197-
metadata => this.installFromZipPath(identifierWithVersion, zipPath, metadata, operation, token),
198-
() => this.installFromZipPath(identifierWithVersion, zipPath, null, operation, token))
197+
metadata => this.installFromZipPath(identifierWithVersion, zipPath, { ...metadata, isDefault }, operation, token),
198+
() => this.installFromZipPath(identifierWithVersion, zipPath, { isDefault }, operation, token))
199199
.then(
200200
local => { this.logService.info('Successfully installed the extension:', identifier.id); return local; },
201201
e => {
@@ -219,7 +219,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
219219
return this.downloadService.download(vsix, URI.file(downloadedLocation)).then(() => URI.file(downloadedLocation));
220220
}
221221

222-
private installFromZipPath(identifierWithVersion: ExtensionIdentifierWithVersion, zipPath: string, metadata: IGalleryMetadata | null, operation: InstallOperation, token: CancellationToken): Promise<ILocalExtension> {
222+
private installFromZipPath(identifierWithVersion: ExtensionIdentifierWithVersion, zipPath: string, metadata: IMetadata, operation: InstallOperation, token: CancellationToken): Promise<ILocalExtension> {
223223
return this.toNonCancellablePromise(this.installExtension({ zipPath, identifierWithVersion, metadata }, token)
224224
.then(local => this.installDependenciesAndPackExtensions(local, null)
225225
.then(
@@ -239,7 +239,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
239239
));
240240
}
241241

242-
async installFromGallery(extension: IGalleryExtension): Promise<ILocalExtension> {
242+
async installFromGallery(extension: IGalleryExtension, isDefault?: boolean): Promise<ILocalExtension> {
243243
if (!this.galleryService.isEnabled()) {
244244
return Promise.reject(new Error(nls.localize('MarketPlaceDisabled', "Marketplace is not enabled")));
245245
}
@@ -287,8 +287,11 @@ export class ExtensionManagementService extends Disposable implements IExtension
287287
}
288288

289289
this.downloadInstallableExtension(extension, operation)
290-
.then(installableExtension => this.installExtension(installableExtension, cancellationToken)
291-
.then(local => this.extensionsDownloader.delete(URI.file(installableExtension.zipPath)).finally(() => { }).then(() => local)))
290+
.then(installableExtension => {
291+
installableExtension.metadata.isDefault = isDefault !== undefined ? isDefault : existingExtension.isDefault;
292+
return this.installExtension(installableExtension, cancellationToken)
293+
.then(local => this.extensionsDownloader.delete(URI.file(installableExtension.zipPath)).finally(() => { }).then(() => local));
294+
})
292295
.then(local => this.installDependenciesAndPackExtensions(local, existingExtension)
293296
.then(() => local, error => this.uninstall(local, true).then(() => Promise.reject(error), () => Promise.reject(error))))
294297
.then(
@@ -358,7 +361,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
358361
.then(report => getMaliciousExtensionsSet(report).has(extension.identifier.id));
359362
}
360363

361-
private downloadInstallableExtension(extension: IGalleryExtension, operation: InstallOperation): Promise<InstallableExtension> {
364+
private downloadInstallableExtension(extension: IGalleryExtension, operation: InstallOperation): Promise<Required<InstallableExtension>> {
362365
const metadata = <IGalleryMetadata>{
363366
id: extension.identifier.uuid,
364367
publisherId: extension.publisherId,
@@ -373,7 +376,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
373376
this.logService.info('Downloaded extension:', extension.identifier.id, zipPath);
374377
return getManifest(zipPath)
375378
.then(
376-
manifest => (<InstallableExtension>{ zipPath, identifierWithVersion: new ExtensionIdentifierWithVersion(extension.identifier, manifest.version), metadata }),
379+
manifest => (<Required<InstallableExtension>>{ zipPath, identifierWithVersion: new ExtensionIdentifierWithVersion(extension.identifier, manifest.version), metadata }),
377380
error => Promise.reject(new ExtensionManagementError(this.joinErrors(error).message, INSTALL_ERROR_VALIDATING))
378381
);
379382
},
@@ -480,14 +483,14 @@ export class ExtensionManagementService extends Disposable implements IExtension
480483

481484
async updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata): Promise<ILocalExtension> {
482485
this.logService.trace('ExtensionManagementService#updateMetadata', local.identifier.id);
483-
local = await this.extensionsScanner.saveMetadataForLocalExtension(local, metadata);
486+
local = await this.extensionsScanner.saveMetadataForLocalExtension(local, { ...metadata, isDefault: local.isDefault });
484487
this.manifestCache.invalidate();
485488
return local;
486489
}
487490

488-
private getMetadata(extensionName: string): Promise<IGalleryMetadata | null> {
491+
private getGalleryMetadata(extensionName: string): Promise<IGalleryMetadata | undefined> {
489492
return this.findGalleryExtensionByName(extensionName)
490-
.then(galleryExtension => galleryExtension ? <IGalleryMetadata>{ id: galleryExtension.identifier.uuid, publisherDisplayName: galleryExtension.publisherDisplayName, publisherId: galleryExtension.publisherId } : null);
493+
.then(galleryExtension => galleryExtension ? <IGalleryMetadata>{ id: galleryExtension.identifier.uuid, publisherDisplayName: galleryExtension.publisherDisplayName, publisherId: galleryExtension.publisherId } : undefined);
491494
}
492495

493496
private findGalleryExtension(local: ILocalExtension): Promise<IGalleryExtension> {

src/vs/platform/extensionManagement/node/extensionsScanner.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ const INSTALL_ERROR_EXTRACTING = 'extracting';
3232
const INSTALL_ERROR_DELETING = 'deleting';
3333
const INSTALL_ERROR_RENAMING = 'renaming';
3434

35+
export type IMetadata = Partial<IGalleryMetadata> & { isDefault: boolean; };
36+
3537
export class ExtensionsScanner extends Disposable {
3638

3739
private readonly systemExtensionsPath: string;
@@ -127,7 +129,7 @@ export class ExtensionsScanner extends Disposable {
127129
throw new Error(localize('cannot read', "Cannot read the extension from {0}", this.extensionsPath));
128130
}
129131

130-
async saveMetadataForLocalExtension(local: ILocalExtension, metadata: IGalleryMetadata): Promise<ILocalExtension> {
132+
async saveMetadataForLocalExtension(local: ILocalExtension, metadata: IMetadata): Promise<ILocalExtension> {
131133
this.setMetadata(local, metadata);
132134
const manifestPath = path.join(local.location.fsPath, 'package.json');
133135
const raw = await pfs.readFile(manifestPath, 'utf8');
@@ -227,7 +229,7 @@ export class ExtensionsScanner extends Disposable {
227229
const changelog = children.filter(child => /^changelog(\.txt|\.md|)$/i.test(child))[0];
228230
const changelogUrl = changelog ? URI.file(path.join(extensionPath, changelog)) : null;
229231
const identifier = { id: getGalleryExtensionId(manifest.publisher, manifest.name) };
230-
const local = <ILocalExtension>{ type, identifier, manifest, location: URI.file(extensionPath), readmeUrl, changelogUrl, publisherDisplayName: null, publisherId: null };
232+
const local = <ILocalExtension>{ type, identifier, manifest, location: URI.file(extensionPath), readmeUrl, changelogUrl, publisherDisplayName: null, publisherId: null, isDefault: false };
231233
if (metadata) {
232234
this.setMetadata(local, metadata);
233235
}
@@ -255,10 +257,11 @@ export class ExtensionsScanner extends Disposable {
255257
}
256258
}
257259

258-
private setMetadata(local: ILocalExtension, metadata: IGalleryMetadata): void {
259-
local.publisherDisplayName = metadata.publisherDisplayName;
260-
local.publisherId = metadata.publisherId;
260+
private setMetadata(local: ILocalExtension, metadata: IMetadata): void {
261+
local.publisherDisplayName = metadata.publisherDisplayName || null;
262+
local.publisherId = metadata.publisherId || null;
261263
local.identifier.uuid = metadata.id;
264+
local.isDefault = metadata.isDefault;
262265
}
263266

264267
private async removeUninstalledExtensions(): Promise<void> {
@@ -314,7 +317,7 @@ export class ExtensionsScanner extends Disposable {
314317
return this._devSystemExtensionsPath;
315318
}
316319

317-
private async readManifest(extensionPath: string): Promise<{ manifest: IExtensionManifest; metadata: IGalleryMetadata | null; }> {
320+
private async readManifest(extensionPath: string): Promise<{ manifest: IExtensionManifest; metadata: IMetadata | null; }> {
318321
const promises = [
319322
pfs.readFile(path.join(extensionPath, 'package.json'), 'utf8')
320323
.then(raw => this.parseManifest(raw)),
@@ -330,7 +333,7 @@ export class ExtensionsScanner extends Disposable {
330333
};
331334
}
332335

333-
private parseManifest(raw: string): Promise<{ manifest: IExtensionManifest; metadata: IGalleryMetadata | null; }> {
336+
private parseManifest(raw: string): Promise<{ manifest: IExtensionManifest; metadata: IMetadata | null; }> {
334337
return new Promise((c, e) => {
335338
try {
336339
const manifest = JSON.parse(raw);

0 commit comments

Comments
 (0)