diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index ea125d6cda4c6c60c25117e9817565db64165357..8fc3cff772a17c9004391ece20d1dc8ad96d8382 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -257,6 +257,8 @@ export interface IExtensionManagementService { installFromGallery(extension: IGalleryExtension): TPromise; uninstall(extension: ILocalExtension, force?: boolean): TPromise; getInstalled(type?: LocalExtensionType): TPromise; + + updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata): TPromise; } export const IExtensionEnablementService = createDecorator('extensionEnablementService'); diff --git a/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts b/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts index 5f5a8c39e747cb09ef5a3635d6aebedd0315752f..15bb2aa58dfd11d24e73eaa4966a6149ba3eaa70 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts @@ -7,7 +7,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { IChannel, eventToCall, eventFromCall } from 'vs/base/parts/ipc/common/ipc'; -import { IExtensionManagementService, ILocalExtension, InstallExtensionEvent, DidInstallExtensionEvent, IGalleryExtension, LocalExtensionType, DidUninstallExtensionEvent, IExtensionIdentifier } from './extensionManagement'; +import { IExtensionManagementService, ILocalExtension, InstallExtensionEvent, DidInstallExtensionEvent, IGalleryExtension, LocalExtensionType, DidUninstallExtensionEvent, IExtensionIdentifier, IGalleryMetadata } from './extensionManagement'; import Event, { buffer } from 'vs/base/common/event'; export interface IExtensionManagementChannel extends IChannel { @@ -46,6 +46,7 @@ export class ExtensionManagementChannel implements IExtensionManagementChannel { case 'installFromGallery': return this.service.installFromGallery(arg[0]); case 'uninstall': return this.service.uninstall(arg[0], arg[1]); case 'getInstalled': return this.service.getInstalled(arg); + case 'updateMetadata': return this.service.updateMetadata(arg[0], arg[1]); } return undefined; } @@ -84,4 +85,8 @@ export class ExtensionManagementChannelClient implements IExtensionManagementSer getInstalled(type: LocalExtensionType = null): TPromise { return this.channel.call('getInstalled', type); } + + updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata): TPromise { + return this.channel.call('updateMetadata', [local, metadata]); + } } \ No newline at end of file diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index ff9dd9a00167ae2b21499cce01d863a5c93d6791..bddb22b6f307e95621ca36408e3ba3314a847351 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -123,11 +123,17 @@ export class ExtensionManagementService implements IExtensionManagementService { this._onInstallExtension.fire({ identifier, zipPath }); - return this.installExtension({ zipPath, id: identifier.id, metadata: null }) - .then( - local => this._onDidInstallExtension.fire({ identifier, zipPath, local }), - error => { this._onDidInstallExtension.fire({ identifier, zipPath, error }); return TPromise.wrapError(error); } - ); + return this.galleryService.query({ names: [getGalleryExtensionId(manifest.publisher, manifest.name)], pageSize: 1 }) + .then(galleryResult => { + const galleryExtension = galleryResult.firstPage[0]; + const metadata = galleryExtension ? { id: galleryExtension.identifier.uuid, publisherDisplayName: galleryExtension.publisherDisplayName, publisherId: galleryExtension.publisherId } : null; + return this.installExtension({ zipPath, id: identifier.id, metadata }) + .then( + local => this._onDidInstallExtension.fire({ identifier, zipPath, local }), + error => { this._onDidInstallExtension.fire({ identifier, zipPath, error }); return TPromise.wrapError(error); } + ); + }); + }); }); } @@ -253,12 +259,8 @@ export class ExtensionManagementService implements IExtensionManagementService { const identifier = { id, uuid: metadata ? metadata.id : null }; const local: ILocalExtension = { type, identifier, manifest, metadata, path: extensionPath, readmeUrl, changelogUrl }; - const manifestPath = path.join(extensionPath, 'package.json'); - return pfs.readFile(manifestPath, 'utf8') - .then(raw => parseManifest(raw)) - .then(({ manifest }) => assign(manifest, { __metadata: metadata })) - .then(manifest => pfs.writeFile(manifestPath, JSON.stringify(manifest, null, '\t'))) + return this.saveMetadataForLocalExtension(local) .then(() => this.checkForRename(current, local)) .then(() => local); }); @@ -279,6 +281,23 @@ export class ExtensionManagementService implements IExtensionManagementService { .then(() => { /* drop resolved value */ }); } + updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata): TPromise { + local.metadata = metadata; + return this.saveMetadataForLocalExtension(local); + } + + private saveMetadataForLocalExtension(local: ILocalExtension): TPromise { + if (!local.metadata) { + return TPromise.as(local); + } + const manifestPath = path.join(this.extensionsPath, local.identifier.id, 'package.json'); + return pfs.readFile(manifestPath, 'utf8') + .then(raw => parseManifest(raw)) + .then(({ manifest }) => assign(manifest, { __metadata: local.metadata })) + .then(manifest => pfs.writeFile(manifestPath, JSON.stringify(manifest, null, '\t'))) + .then(() => local); + } + private checkForRename(currentExtension: ILocalExtension, newExtension: ILocalExtension): TPromise { // Check if the gallery id for current and new exensions are same, if not, remove the current one. if (currentExtension && getGalleryExtensionIdFromLocal(currentExtension) !== getGalleryExtensionIdFromLocal(newExtension)) { diff --git a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts index 5ff2eb89af6a79d5a72b0e0b12695878fafc82b4..a1fd8c446092e2b76e1f88b79cc701af8e96d11b 100644 --- a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts +++ b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts @@ -459,9 +459,14 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService { } private syncLocalWithGalleryExtension(local: Extension, gallery: IGalleryExtension) { - local.gallery = gallery; - this._onChange.fire(); - this.eventuallyAutoUpdateExtensions(); + // Sync the local extension with gallery extension if local extension doesnot has metadata + (local.local.metadata ? TPromise.as(local.local) : this.extensionService.updateMetadata(local.local, { id: gallery.identifier.uuid, publisherDisplayName: gallery.publisherDisplayName, publisherId: gallery.publisherId })) + .then(localExtension => { + local.local = localExtension; + local.gallery = gallery; + this._onChange.fire(); + this.eventuallyAutoUpdateExtensions(); + }); } checkForUpdates(): TPromise {