diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index 41eef54d29624f3909925c27e525d7f47538cde8..902181688da9c8a6028919dc4195a2c02892abd6 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -109,11 +109,6 @@ export interface IExtensionManifest { contributes?: IExtensionContributions; } -export interface IExtensionIdentity { - name: string; - publisher: string; -} - export interface IGalleryExtensionProperties { dependencies?: string[]; engine?: string; @@ -135,6 +130,7 @@ export interface IGalleryExtensionAssets { export interface IGalleryExtension { uuid: string; + id: string; name: string; version: string; date: string; diff --git a/src/vs/platform/extensionManagement/common/extensionTelemetry.ts b/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts similarity index 57% rename from src/vs/platform/extensionManagement/common/extensionTelemetry.ts rename to src/vs/platform/extensionManagement/common/extensionManagementUtil.ts index 0217e2803f9979ba34b2e76ac4d98c24684de4d6..4961a989d60b379dd4de897d171aa171f88da2d5 100644 --- a/src/vs/platform/extensionManagement/common/extensionTelemetry.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts @@ -5,11 +5,31 @@ 'use strict'; -import { ILocalExtension, IGalleryExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { ILocalExtension, IGalleryExtension, IExtensionManifest } from 'vs/platform/extensionManagement/common/extensionManagement'; + +export function getGalleryExtensionId(publisher: string, name: string): string { + return `${publisher}.${name.toLocaleLowerCase()}`; +} + +export function getLocalExtensionIdFromGallery(extension: IGalleryExtension, version: string): string { + return getLocalExtensionId(extension.id, version); +} + +export function getLocalExtensionIdFromManifest(manifest: IExtensionManifest): string { + return getLocalExtensionId(getGalleryExtensionId(manifest.publisher, manifest.name), manifest.version); +} + +export function getGalleryExtensionIdFromLocal(local: ILocalExtension): string { + return local.id.replace(/-\d+\.\d+\.\d+$/, ''); +} + +function getLocalExtensionId(id: string, version: string): string { + return `${id}-${version}`; +} export function getLocalExtensionTelemetryData(extension: ILocalExtension): any { return { - id: `${extension.manifest.publisher}.${extension.manifest.name}`, + id: getGalleryExtensionIdFromLocal(extension), name: extension.manifest.name, galleryId: extension.metadata ? extension.metadata.uuid : null, publisherId: extension.metadata ? extension.metadata.publisherId : null, @@ -21,7 +41,7 @@ export function getLocalExtensionTelemetryData(extension: ILocalExtension): any export function getGalleryExtensionTelemetryData(extension: IGalleryExtension): any { return { - id: `${extension.publisher}.${extension.name}`, + id: extension.id, name: extension.name, galleryId: extension.uuid, publisherId: extension.publisherId, diff --git a/src/vs/platform/extensionManagement/node/extensionGalleryService.ts b/src/vs/platform/extensionManagement/node/extensionGalleryService.ts index 66ebe7c202e72bdb8850515b352587ddf391690b..fe1fba0a30b2a81574c8c9336648b05acc5d9a3c 100644 --- a/src/vs/platform/extensionManagement/node/extensionGalleryService.ts +++ b/src/vs/platform/extensionManagement/node/extensionGalleryService.ts @@ -11,7 +11,7 @@ import { distinct } from 'vs/base/common/arrays'; import { getErrorMessage } from 'vs/base/common/errors'; import { ArraySet } from 'vs/base/common/set'; import { IGalleryExtension, IExtensionGalleryService, IGalleryExtensionAsset, IQueryOptions, SortBy, SortOrder, IExtensionManifest } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { getGalleryExtensionTelemetryData } from 'vs/platform/extensionManagement/common/extensionTelemetry'; +import { getGalleryExtensionId, getGalleryExtensionTelemetryData } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { assign, getOrDefault } from 'vs/base/common/objects'; import { IRequestService } from 'vs/platform/request/node/request'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; @@ -241,6 +241,7 @@ function toExtension(galleryExtension: IRawGalleryExtension, extensionsGalleryUr return { uuid: galleryExtension.extensionId, + id: getGalleryExtensionId(galleryExtension.publisher.publisherName, galleryExtension.extensionName), name: galleryExtension.extensionName, version: version.version, date: version.lastUpdated, diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index f7df01537ef419cca28001a8e957c7be556fa5c2..1537a1fe520839c87df149afd938a11805cee6be 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -16,9 +16,10 @@ import { extract, buffer } from 'vs/base/node/zip'; import { Promise, TPromise } from 'vs/base/common/winjs.base'; import { IExtensionManagementService, IExtensionGalleryService, ILocalExtension, - IGalleryExtension, IExtensionIdentity, IExtensionManifest, IGalleryMetadata, + IGalleryExtension, IExtensionManifest, IGalleryMetadata, InstallExtensionEvent, DidInstallExtensionEvent, DidUninstallExtensionEvent, LocalExtensionType } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { getLocalExtensionIdFromGallery, getLocalExtensionIdFromManifest } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { localizeManifest } from '../common/extensionNls'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { Limiter } from 'vs/base/common/async'; @@ -43,26 +44,10 @@ function parseManifest(raw: string): TPromise<{ manifest: IExtensionManifest; me }); } -function validate(zipPath: string, extension?: IExtensionIdentity, version?: string): TPromise { +function validate(zipPath: string): TPromise { return buffer(zipPath, 'extension/package.json') .then(buffer => parseManifest(buffer.toString('utf8'))) - .then(({ manifest }) => { - if (extension) { - if (extension.name !== manifest.name) { - return Promise.wrapError(Error(nls.localize('invalidName', "Extension invalid: manifest name mismatch."))); - } - - if (extension.publisher !== manifest.publisher) { - return Promise.wrapError(Error(nls.localize('invalidPublisher', "Extension invalid: manifest publisher mismatch."))); - } - - if (version !== manifest.version) { - return Promise.wrapError(Error(nls.localize('invalidVersion', "Extension invalid: manifest version mismatch."))); - } - } - - return TPromise.as(manifest); - }); + .then(({ manifest }) => TPromise.as(manifest)); } function readManifest(extensionPath: string): TPromise<{ manifest: IExtensionManifest; metadata: IGalleryMetadata; }> { @@ -82,10 +67,6 @@ function readManifest(extensionPath: string): TPromise<{ manifest: IExtensionMan }); } -function getExtensionId(extension: IExtensionIdentity, version: string): string { - return `${extension.publisher}.${extension.name}-${version}`; -} - export class ExtensionManagementService implements IExtensionManagementService { _serviceBrand: any; @@ -121,7 +102,7 @@ export class ExtensionManagementService implements IExtensionManagementService { zipPath = path.resolve(zipPath); return validate(zipPath).then(manifest => { - const id = getExtensionId(manifest, manifest.version); + const id = getLocalExtensionIdFromManifest(manifest); return this.isObsolete(id).then(isObsolete => { if (isObsolete) { @@ -140,7 +121,7 @@ export class ExtensionManagementService implements IExtensionManagementService { } installFromGallery(extension: IGalleryExtension, promptToInstallDependencies: boolean = true): TPromise { - const id = getExtensionId(extension, extension.version); + const id = getLocalExtensionIdFromGallery(extension, extension.version); return this.isObsolete(id).then(isObsolete => { if (isObsolete) { @@ -204,7 +185,7 @@ export class ExtensionManagementService implements IExtensionManagementService { private installWithDependencies(extension: IGalleryExtension): TPromise { return this.galleryService.getAllDependencies(extension) .then(allDependencies => this.filterDependenciesToInstall(extension, allDependencies)) - .then(toInstall => this.filterObsolete(...toInstall.map(i => getExtensionId(i, i.version))) + .then(toInstall => this.filterObsolete(...toInstall.map(i => getLocalExtensionIdFromGallery(i, i.version))) .then((obsolete) => { if (obsolete.length) { return TPromise.wrapError(new Error(nls.localize('restartCode', "Please restart Code before reinstalling {0}.", extension.displayName || extension.name))); @@ -216,7 +197,7 @@ export class ExtensionManagementService implements IExtensionManagementService { private bulkInstallWithDependencies(extension: IGalleryExtension, dependecies: IGalleryExtension[]): TPromise { for (const dependency of dependecies) { - const id = getExtensionId(dependency, dependency.version); + const id = getLocalExtensionIdFromGallery(dependency, dependency.version); this._onInstallExtension.fire({ id, gallery: dependency }); } return this.downloadAndInstall(extension) @@ -236,7 +217,7 @@ export class ExtensionManagementService implements IExtensionManagementService { }) .then(localExtension => localExtension, error => { for (const dependency of dependecies) { - this._onDidInstallExtension.fire({ id: getExtensionId(dependency, dependency.version), gallery: dependency, error }); + this._onDidInstallExtension.fire({ id: getLocalExtensionIdFromGallery(dependency, dependency.version), gallery: dependency, error }); } return TPromise.wrapError(error); }); @@ -256,7 +237,7 @@ export class ExtensionManagementService implements IExtensionManagementService { if (extension.uuid === d.uuid) { return false; } - const extensionId = getExtensionId(d, d.version); + const extensionId = getLocalExtensionIdFromGallery(d, d.version); return local.every(local => local.id !== extensionId); }); }); @@ -268,12 +249,12 @@ export class ExtensionManagementService implements IExtensionManagementService { } private getGalleryExtensionForLocalExtension(galleryExtensions: IGalleryExtension[], localExtension: ILocalExtension): IGalleryExtension { - const filtered = galleryExtensions.filter(galleryExtension => getExtensionId(galleryExtension, galleryExtension.version) === localExtension.id); + const filtered = galleryExtensions.filter(galleryExtension => getLocalExtensionIdFromGallery(galleryExtension, galleryExtension.version) === localExtension.id); return filtered.length ? filtered[0] : null; } private downloadAndInstall(extension: IGalleryExtension): TPromise { - const id = getExtensionId(extension, extension.version); + const id = getLocalExtensionIdFromGallery(extension, extension.version); const metadata = { uuid: extension.uuid, publisherId: extension.publisherId, diff --git a/src/vs/platform/extensionManagement/node/extensionManagementUtil.ts b/src/vs/platform/extensionManagement/node/extensionManagementUtil.ts deleted file mode 100644 index 4fdb1a5103bc4af4f37b1c6de10f767a0809ec03..0000000000000000000000000000000000000000 --- a/src/vs/platform/extensionManagement/node/extensionManagementUtil.ts +++ /dev/null @@ -1,66 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -'use strict'; - -import { IExtensionIdentity, ILocalExtension, IGalleryExtension, IExtensionManagementService, IExtensionGalleryService, LocalExtensionType } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { TPromise } from 'vs/base/common/winjs.base'; -import * as semver from 'semver'; - -export function extensionEquals(one: IExtensionIdentity, other: IExtensionIdentity): boolean { - return one.publisher === other.publisher && one.name === other.name; -} - -export function getTelemetryData(extension: ILocalExtension | IGalleryExtension) { - const local = extension as ILocalExtension; - const gallery = extension as IGalleryExtension; - - if (local.path) { - return { - id: `${local.manifest.publisher}.${local.manifest.name}`, - name: local.manifest.name, - galleryId: local.metadata ? local.metadata.uuid : null, - publisherId: local.metadata ? local.metadata.publisherId : null, - publisherName: local.manifest.publisher, - publisherDisplayName: local.metadata ? local.metadata.publisherDisplayName : null - }; - } else { - return { - id: `${gallery.publisher}.${gallery.name}`, - name: gallery.name, - galleryId: gallery.uuid, - publisherId: gallery.publisherId, - publisherName: gallery.publisher, - publisherDisplayName: gallery.publisherDisplayName - }; - } -} - -export function getOutdatedExtensions(extensionsService: IExtensionManagementService, galleryService: IExtensionGalleryService): TPromise { - if (!galleryService.isEnabled()) { - return TPromise.as([]); - } - - return extensionsService.getInstalled(LocalExtensionType.User).then(installed => { - const names = installed.map(({ manifest }) => `${manifest.publisher}.${manifest.name}`); - - if (installed.length === 0) { - return TPromise.as([]); - } - - return galleryService.query({ names, pageSize: names.length }).then(result => { - const available = result.firstPage; - - return available.map(extension => { - const local = installed.filter(local => extensionEquals(local.manifest, extension))[0]; - if (local && semver.lt(local.manifest.version, extension.version)) { - return local; - } else { - return null; - } - }).filter(e => !!e); - }); - }); -} \ No newline at end of file diff --git a/src/vs/workbench/parts/extensions/browser/extensionEditor.ts b/src/vs/workbench/parts/extensions/browser/extensionEditor.ts index 8703badd4227737766ecb9bdee9a15642f10c6fb..5cdc8d8b6e364ce3d5ccffa50e5df1e580170bc4 100644 --- a/src/vs/workbench/parts/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/parts/extensions/browser/extensionEditor.ts @@ -237,7 +237,7 @@ export class ExtensionEditor extends BaseEditor { this.icon.src = extension.iconUrl; this.name.textContent = extension.displayName; - this.identifier.textContent = `${extension.publisher}.${extension.name}`; + this.identifier.textContent = extension.identifier; this.publisher.textContent = extension.publisherDisplayName; this.description.textContent = extension.description; diff --git a/src/vs/workbench/parts/extensions/browser/extensionsActions.ts b/src/vs/workbench/parts/extensions/browser/extensionsActions.ts index a3cc09bf40c3f8bff2ce7dffb04d26e004882de2..9afaba9ac2251f1fbe532764fd4f1c00f6922789 100644 --- a/src/vs/workbench/parts/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/parts/extensions/browser/extensionsActions.ts @@ -124,7 +124,7 @@ export class UninstallAction extends Action { this.label = UninstallAction.UninstallLabel; this.class = UninstallAction.UninstallClass; - const installedExtensions = this.extensionsWorkbenchService.local.filter(e => e.identifier === this.extension.identifier); + const installedExtensions = this.extensionsWorkbenchService.local.filter(e => e.id === this.extension.id); if (!installedExtensions.length) { this.enabled = false; @@ -761,7 +761,7 @@ export class ReloadAction extends Action { } private computeReloadState(runningExtensions: IExtensionDescription[]): void { - const isInstalled = this.extensionsWorkbenchService.local.some(e => e.identifier === this.extension.identifier); + const isInstalled = this.extensionsWorkbenchService.local.some(e => e.id === this.extension.id); const isUninstalled = this.extension.state === ExtensionState.Uninstalled; const isDisabled = this.extension.disabledForWorkspace || this.extension.disabledGlobally; diff --git a/src/vs/workbench/parts/extensions/browser/extensionsList.ts b/src/vs/workbench/parts/extensions/browser/extensionsList.ts index 88bb1de5ce3da30ea8dac804ccc2b9d061ccbff8..184718f4bdbe8c743d6bbe35497409051005d5a2 100644 --- a/src/vs/workbench/parts/extensions/browser/extensionsList.ts +++ b/src/vs/workbench/parts/extensions/browser/extensionsList.ts @@ -129,7 +129,7 @@ export class Renderer implements IPagedRenderer { this.extensionService.getExtensions().then(enabledExtensions => { const isExtensionRunning = enabledExtensions.some(e => e.id === extension.identifier); - const isInstalled = this.extensionsWorkbenchService.local.some(e => e.identifier === extension.identifier); + const isInstalled = this.extensionsWorkbenchService.local.some(e => e.id === extension.id); toggleClass(data.element, 'disabled', isInstalled && !isExtensionRunning); }); diff --git a/src/vs/workbench/parts/extensions/common/extensions.ts b/src/vs/workbench/parts/extensions/common/extensions.ts index 01ac0bdb78e7224f15808d2f4e13873536c5c8ec..2fdfd1f4968080c3bdf5b085f3fec3b91ba7560f 100644 --- a/src/vs/workbench/parts/extensions/common/extensions.ts +++ b/src/vs/workbench/parts/extensions/common/extensions.ts @@ -29,6 +29,7 @@ export interface IExtension { name: string; displayName: string; identifier: string; + id: string; publisher: string; publisherDisplayName: string; version: string; diff --git a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts index 9c828148216071e9159665abaf6fd8264087c63e..ce0896624840725b7c7608af276767b2436d5572 100644 --- a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts +++ b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts @@ -23,7 +23,7 @@ import { IExtensionManagementService, IExtensionGalleryService, ILocalExtension, IGalleryExtension, IQueryOptions, IExtensionManifest, InstallExtensionEvent, DidInstallExtensionEvent, LocalExtensionType, DidUninstallExtensionEvent, IExtensionEnablementService, IExtensionTipsService } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData } from 'vs/platform/extensionManagement/common/extensionTelemetry'; +import { getGalleryExtensionIdFromLocal, getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IChoiceService, IMessageService } from 'vs/platform/message/common/message'; @@ -72,6 +72,13 @@ class Extension implements IExtension { return `${this.publisher}.${this.name}`; } + get id(): string { + if (this.gallery) { + return this.gallery.id; + } + return getGalleryExtensionIdFromLocal(this.local); + } + get publisher(): string { return this.gallery ? this.gallery.publisher : this.local.manifest.publisher; } @@ -267,10 +274,6 @@ class ExtensionDependencies implements IExtensionDependencies { } } -function stripVersion(id: string): string { - return id.replace(/-\d+\.\d+\.\d+$/, ''); -} - enum Operation { Installing, Updating, @@ -278,7 +281,6 @@ enum Operation { } interface IActiveExtension { - id: string; operation: Operation; extension: Extension; start: Date; @@ -344,7 +346,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService { get local(): IExtension[] { const installing = this.installing - .filter(e => !this.installed.some(installed => stripVersion(installed.local.id) === e.id)) + .filter(e => !this.installed.some(installed => installed.id === e.extension.id)) .map(e => e.extension); return [...this.installed, ...installing]; @@ -391,7 +393,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService { .then(extensions => { const map = new Map(); for (const extension of extensions) { - map.set(`${extension.publisher}.${extension.name}`, extension); + map.set(extension.identifier, extension); } return new ExtensionDependencies(extension, extension.identifier, map); }); @@ -402,8 +404,8 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService { } private fromGallery(gallery: IGalleryExtension): Extension { - const installedByGalleryId = index(this.installed, e => e.identifier); - const installed = installedByGalleryId[`${gallery.publisher}.${gallery.name}`]; + const installedByGalleryId = index(this.installed, e => e.id); + const installed = installedByGalleryId[gallery.id]; if (installed) { // Loading the compatible version only there is an engine property @@ -508,7 +510,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService { } const ext = extension as Extension; - const local = ext.local || this.installed.filter(e => e.local.metadata && ext.gallery && e.local.metadata.uuid === ext.gallery.uuid)[0].local; + const local = ext.local || this.installed.filter(e => e.id === extension.id)[0].local; if (!local) { return TPromise.wrapError(new Error('Missing local')); @@ -646,13 +648,13 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService { } private onInstallExtension(event: InstallExtensionEvent): void { - const { id, gallery } = event; + const { gallery } = event; if (!gallery) { return; } - let extension = this.installed.filter(e => (e.local && e.local.metadata && e.local.metadata.uuid) === gallery.uuid)[0]; + let extension = this.installed.filter(e => e.id === gallery.id)[0]; if (!extension) { extension = new Extension(this.galleryService, this.stateProvider, null, gallery); @@ -662,28 +664,26 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService { const start = new Date(); const operation = Operation.Installing; - this.installing.push({ id: stripVersion(id), operation, extension, start }); + this.installing.push({ operation, extension, start }); this._onChange.fire(); } private onDidInstallExtension(event: DidInstallExtensionEvent): void { - const { local, zipPath, error } = event; - const id = stripVersion(event.id); - const installing = this.installing.filter(e => e.id === id)[0]; - + const { local, zipPath, error, gallery } = event; + const installing = gallery ? this.installing.filter(e => e.extension.id === gallery.id)[0] : null; const extension: Extension = installing ? installing.extension : zipPath ? new Extension(this.galleryService, this.stateProvider, null) : null; if (extension) { - this.installing = this.installing.filter(e => e.id !== id); + this.installing = installing ? this.installing.filter(e => e !== installing) : this.installing; if (!error) { extension.local = local; - const galleryId = local.metadata && local.metadata.uuid; - const installed = this.installed.filter(e => (e.local && e.local.metadata && e.local.metadata.uuid) === galleryId)[0]; - - if (galleryId && installed) { - installing.operation = Operation.Updating; + const installed = this.installed.filter(e => e.id === extension.id)[0]; + if (installed) { + if (installing) { + installing.operation = Operation.Updating; + } installed.local = local; } else { this.installed.push(extension); @@ -707,8 +707,8 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService { const start = new Date(); const operation = Operation.Uninstalling; - const uninstalling = this.uninstalling.filter(e => e.id === id)[0] || { id, operation, extension, start }; - this.uninstalling = [uninstalling, ...this.uninstalling.filter(e => e.id !== id)]; + const uninstalling = this.uninstalling.filter(e => e.extension.local.id === id)[0] || { id, operation, extension, start }; + this.uninstalling = [uninstalling, ...this.uninstalling.filter(e => e.extension.local.id !== id)]; this._onChange.fire(); } @@ -718,8 +718,8 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService { this.installed = this.installed.filter(e => e.local.id !== id); } - const uninstalling = this.uninstalling.filter(e => e.id === id)[0]; - this.uninstalling = this.uninstalling.filter(e => e.id !== id); + const uninstalling = this.uninstalling.filter(e => e.extension.local.id === id)[0]; + this.uninstalling = this.uninstalling.filter(e => e.extension.local.id !== id); if (!uninstalling) { return; } @@ -743,15 +743,15 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService { } private getExtensionState(extension: Extension): ExtensionState { - if (extension.gallery && this.installing.some(e => e.extension.gallery && e.extension.gallery.uuid === extension.gallery.uuid)) { + if (extension.gallery && this.installing.some(e => e.extension.gallery && e.extension.gallery.id === extension.gallery.id)) { return ExtensionState.Installing; } - if (this.uninstalling.some(e => e.extension.identifier === extension.identifier)) { + if (this.uninstalling.some(e => e.extension.id === extension.id)) { return ExtensionState.Uninstalling; } - const local = this.installed.filter(e => e === extension || (e.gallery && extension.gallery && e.gallery.uuid === extension.gallery.uuid))[0]; + const local = this.installed.filter(e => e === extension || (e.gallery && extension.gallery && e.gallery.id === extension.gallery.id))[0]; return local ? ExtensionState.Installed : ExtensionState.Uninstalled; } @@ -795,7 +795,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService { const extension = result.firstPage[0]; const promises = [this.open(extension)]; - if (this.local.every(local => local.identifier !== extension.identifier)) { + if (this.local.every(local => local.id !== extension.id)) { promises.push(this.install(extension)); } diff --git a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts index df56434a75c952eaad0422aadeeb16fe9605f521..7d48f016c5103f7bea1f4a40a129748ca91c3576 100644 --- a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts +++ b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts @@ -16,6 +16,7 @@ import { IExtensionManagementService, IExtensionGalleryService, IExtensionEnablementService, IExtensionTipsService, ILocalExtension, LocalExtensionType, IGalleryExtension, DidInstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionEvent } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { getLocalExtensionIdFromManifest, getGalleryExtensionId, getLocalExtensionIdFromGallery } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService'; import { ExtensionTipsService } from 'vs/workbench/parts/extensions/electron-browser/extensionTipsService'; import { TestExtensionEnablementService } from 'vs/platform/extensionManagement/test/common/extensionEnablementService.test'; @@ -961,7 +962,7 @@ suite('ExtensionsActions Test', () => { instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); instantiationService.get(IExtensionsWorkbenchService).queryGallery().done((paged) => { testObject.extension = paged.firstPage[0]; - const id = `${gallery.publisher}.${gallery.name}`; + const id = getLocalExtensionIdFromGallery(gallery, gallery.version); installEvent.fire({ id, gallery }); didInstallEvent.fire({ id, gallery, local: aLocalExtension('a', gallery, { id }) }); uninstallEvent.fire(id); @@ -990,7 +991,7 @@ suite('ExtensionsActions Test', () => { }); test('Test ReloadAction when extension is uninstalled and installed', (done) => { - instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ id: 'pub.a' }]); + instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ id: 'pub.a', version: '1.0.0' }]); const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); @@ -998,9 +999,11 @@ suite('ExtensionsActions Test', () => { testObject.extension = extensions[0]; uninstallEvent.fire(local.id); didUninstallEvent.fire({ id: local.id }); - const gallery = aGalleryExtension('a', { id: local.id }); - installEvent.fire({ id: local.id, gallery }); - didInstallEvent.fire({ id: gallery.uuid, gallery, local }); + + const gallery = aGalleryExtension('a'); + const id = getLocalExtensionIdFromGallery(gallery, gallery.version); + installEvent.fire({ id, gallery }); + didInstallEvent.fire({ id, gallery, local }); assert.ok(!testObject.enabled); done(); @@ -1065,7 +1068,7 @@ suite('ExtensionsActions Test', () => { }); test('Test ReloadAction when extension enablement is toggled when running', (done) => { - instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ id: 'pub.a' }]); + instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ id: 'pub.a', version: '1.0.0' }]); const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction); const local = aLocalExtension('a'); const workbenchService = instantiationService.get(IExtensionsWorkbenchService); @@ -1139,17 +1142,19 @@ suite('ExtensionsActions Test', () => { function aLocalExtension(name: string = 'someext', manifest: any = {}, properties: any = {}): ILocalExtension { const localExtension = Object.create({ manifest: {} }); - assign(localExtension, { type: LocalExtensionType.User, id: generateUuid() }, properties); - assign(localExtension.manifest, { name, publisher: 'pub' }, manifest); + assign(localExtension, { type: LocalExtensionType.User, manifest: {} }, properties); + assign(localExtension.manifest, { name, publisher: 'pub', version: '1.0.0' }, manifest); localExtension.metadata = { uuid: localExtension.id, publisherId: localExtension.manifest.publisher, publisherDisplayName: 'somename' }; + localExtension.id = getLocalExtensionIdFromManifest(localExtension.manifest); return localExtension; } function aGalleryExtension(name: string, properties: any = {}, galleryExtensionProperties: any = {}, assets: any = {}): IGalleryExtension { const galleryExtension = Object.create({}); - assign(galleryExtension, { name, publisher: 'pub', uuid: generateUuid(), properties: {}, assets: {} }, properties); + assign(galleryExtension, { name, publisher: 'pub', uuid: generateUuid(), version: '1.0.0', properties: {}, assets: {} }, properties); assign(galleryExtension.properties, { dependencies: [] }, galleryExtensionProperties); assign(galleryExtension.assets, assets); + galleryExtension.id = getGalleryExtensionId(galleryExtension.publisher, galleryExtension.name); return galleryExtension; } diff --git a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts index 0d20f534b22667d34a066d601cacf7719237019d..86d9945350c2cd1d7f45f82a5a540bb9f8671841 100644 --- a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts +++ b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts @@ -17,6 +17,7 @@ import { IExtensionManagementService, IExtensionGalleryService, IExtensionEnablementService, IExtensionTipsService, ILocalExtension, LocalExtensionType, IGalleryExtension, DidInstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionEvent, IGalleryExtensionAssets } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { getLocalExtensionIdFromManifest, getGalleryExtensionId, getLocalExtensionIdFromGallery } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService'; import { ExtensionTipsService } from 'vs/workbench/parts/extensions/electron-browser/extensionTipsService'; import { TestExtensionEnablementService } from 'vs/platform/extensionManagement/test/common/extensionEnablementService.test'; @@ -306,7 +307,7 @@ suite('ExtensionsWorkbenchService Test', () => { assert.equal(ExtensionState.Uninstalled, extension.state); testObject.install(extension); - const id = `${gallery.publisher}.${gallery.name}`; + const id = getLocalExtensionIdFromGallery(gallery, gallery.version); // Installing installEvent.fire({ id, gallery }); @@ -980,9 +981,10 @@ suite('ExtensionsWorkbenchService Test', () => { function aLocalExtension(name: string = 'someext', manifest: any = {}, properties: any = {}): ILocalExtension { const localExtension = Object.create({ manifest: {} }); - assign(localExtension, { type: LocalExtensionType.User, id: generateUuid(), manifest: {} }, properties); - assign(localExtension.manifest, { name, publisher: 'pub' }, manifest); + assign(localExtension, { type: LocalExtensionType.User, manifest: {} }, properties); + assign(localExtension.manifest, { name, publisher: 'pub', version: '1.0.0' }, manifest); localExtension.metadata = { uuid: localExtension.id, publisherId: localExtension.manifest.publisher, publisherDisplayName: 'somename' }; + localExtension.id = getLocalExtensionIdFromManifest(localExtension.manifest); return localExtension; } @@ -997,9 +999,10 @@ suite('ExtensionsWorkbenchService Test', () => { function aGalleryExtension(name: string, properties: any = {}, galleryExtensionProperties: any = {}, assets: IGalleryExtensionAssets = noAssets): IGalleryExtension { const galleryExtension = Object.create({}); - assign(galleryExtension, { name, publisher: 'pub', uuid: generateUuid(), properties: {}, assets: {} }, properties); + assign(galleryExtension, { name, publisher: 'pub', uuid: generateUuid(), version: '1.0.0', properties: {}, assets: {} }, properties); assign(galleryExtension.properties, { dependencies: [] }, galleryExtensionProperties); assign(galleryExtension.assets, assets); + galleryExtension.id = getGalleryExtensionId(galleryExtension.publisher, galleryExtension.name); return galleryExtension; }