diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index 84989938f7839fb8ab69804aee66ef4851ec3c91..2fdebb22f56ebf8cd273b752101a82d863a29fd3 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -539,11 +539,14 @@ export class ExtensionManagementService extends Disposable implements IExtension return this.preUninstallExtension(extension) .then(() => { if (force) { - return this.uninstallExtensionAsPack(extension, installed); + return this.uninstallExtensionWithDependenciesAndPacked(extension, installed); + } + const dependencies = this.getDependenciesToUninstall(extension, installed); + if (dependencies.length) { + return this.promptForDependenciesAndUninstall(extension, installed); + } else { + return this.uninstallExtensionWithDependenciesAndPacked(extension, installed); } - const hasInstalledExtensionPack = extension.manifest.extensionPack && extension.manifest.extensionPack.length && installed.some(i => extension.manifest.extensionPack.some(dep => areSameExtensions({ id: dep }, i.galleryIdentifier))); - const hasDependencies = extension.manifest.extensionDependencies && extension.manifest.extensionDependencies.length > 0; - return hasInstalledExtensionPack || hasDependencies ? this.promptForPackAndUninstall(extension, installed) : this.uninstallExtensions(extension, [], installed); }) .then(() => this.postUninstallExtension(extension), error => { @@ -552,27 +555,27 @@ export class ExtensionManagementService extends Disposable implements IExtension }); } - private promptForPackAndUninstall(extension: ILocalExtension, installed: ILocalExtension[]): TPromise { - const message = nls.localize('uninstallExtensionPackConfirmation', "Would you like to uninstall '{0}' only or as a pack?", extension.manifest.displayName || extension.manifest.name); + private promptForDependenciesAndUninstall(extension: ILocalExtension, installed: ILocalExtension[]): TPromise { + const message = nls.localize('uninstallDependeciesConfirmation', "Would you like to uninstall '{0}' only or its dependencies also?", extension.manifest.displayName || extension.manifest.name); const buttons = [ - nls.localize('uninstallPack', "Uninstall Extension Pack"), - nls.localize('uninstallOnly', "Uninstall Extension Only"), + nls.localize('uninstallOnly', "Extension Only"), + nls.localize('uninstallAll', "Uninstall All"), nls.localize('cancel', "Cancel") ]; return this.dialogService.show(Severity.Info, message, buttons, { cancelId: 2 }) .then(value => { if (value === 0) { - return this.uninstallExtensionAsPack(extension, installed); + return this.uninstallExtensions(extension, [], installed); } if (value === 1) { - return this.uninstallExtensions(extension, [], installed); + return this.uninstallExtensionWithDependenciesAndPacked(extension, installed); } this.logService.info('Cancelled uninstalling extension:', extension.identifier.id); return TPromise.wrapError(errors.canceled()); }, error => TPromise.wrapError(errors.canceled())); } - private uninstallExtensionAsPack(extension: ILocalExtension, installed: ILocalExtension[]): TPromise { + private uninstallExtensionWithDependenciesAndPacked(extension: ILocalExtension, installed: ILocalExtension[]): TPromise { const extensionsToUninstall = this.getDependenciesToUninstall(extension, installed); for (const packExtensionToUninstall of this.getAllPackExtensionsToUninstall(extension, installed)) { if (extensionsToUninstall.indexOf(packExtensionToUninstall) === -1) { diff --git a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts index a492f570789d3bc5744f911ad253d82fe11738f4..576f2f5445505be7728d124f886d20d1baa02083 100644 --- a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts +++ b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts @@ -742,38 +742,45 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, } private promptAndSetEnablement(extensions: IExtension[], enablementState: EnablementState): TPromise { - const allDependenciesAndPackedExtensions = this.getDependenciesAndPackedExtensionsRecursively(extensions, this.local, enablementState); - if (allDependenciesAndPackedExtensions.length > 0) { - if (extensions.length === 1 && (enablementState === EnablementState.Disabled || enablementState === EnablementState.WorkspaceDisabled)) { - return this.promptForDependenciesAndDisable(extensions[0], allDependenciesAndPackedExtensions, enablementState); + const enable = enablementState === EnablementState.Enabled || enablementState === EnablementState.WorkspaceEnabled; + if (enable) { + return this.checkAndSetEnablementWithDependenciesAndPacked(extensions, enablementState); + } else { + const dependencies = this.getExtensionsRecursively(extensions, this.local, enablementState, { dependencies: true, pack: false }); + if (dependencies.length) { + return this.promptForDependenciesAndDisable(extensions, enablementState); } else { - return this.checkAndSetEnablement(extensions, allDependenciesAndPackedExtensions, enablementState); + return this.checkAndSetEnablementWithDependenciesAndPacked(extensions, enablementState); } } - return this.checkAndSetEnablement(extensions, [], enablementState); } - private promptForDependenciesAndDisable(extension: IExtension, dependencies: IExtension[], enablementState: EnablementState): TPromise { - const message = nls.localize('disableExtensionPackConfirmation', "Would you like to disable '{0}' only or as a pack?", extension.displayName); + private promptForDependenciesAndDisable(extensions: IExtension[], enablementState: EnablementState): TPromise { + const message = nls.localize('disableDependeciesConfirmation', "Would you like to disable the dependencies of the extensions also?"); const buttons = [ - nls.localize('disablePack', "Disable Extension Pack"), - nls.localize('disableOnly', "Disable Extension Only"), + nls.localize('yes', "Yes"), + nls.localize('no', "No"), nls.localize('cancel', "Cancel") ]; - return this.dialogService.show(Severity.Info, message, buttons) + return this.dialogService.show(Severity.Info, message, buttons, { cancelId: 2 }) .then(value => { if (value === 0) { - return this.checkAndSetEnablement([extension], dependencies, enablementState); + return this.checkAndSetEnablementWithDependenciesAndPacked(extensions, enablementState); } if (value === 1) { - return this.checkAndSetEnablement([extension], [], enablementState); + return this.checkAndSetEnablement(extensions, [], enablementState); } return TPromise.as(null); }); } - private checkAndSetEnablement(extensions: IExtension[], dependencies: IExtension[], enablementState: EnablementState): TPromise { - const allExtensions = [...extensions, ...dependencies]; + private checkAndSetEnablementWithDependenciesAndPacked(extensions: IExtension[], enablementState: EnablementState): TPromise { + const otherExtensions = this.getExtensionsRecursively(extensions, this.local, enablementState, { dependencies: true, pack: true }); + return this.checkAndSetEnablement(extensions, otherExtensions, enablementState); + } + + private checkAndSetEnablement(extensions: IExtension[], otherExtensions: IExtension[], enablementState: EnablementState): TPromise { + const allExtensions = [...extensions, ...otherExtensions]; const enable = enablementState === EnablementState.Enabled || enablementState === EnablementState.WorkspaceEnabled; if (!enable) { for (const extension of extensions) { @@ -786,7 +793,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, return TPromise.join(allExtensions.map(e => this.doSetEnablement(e, enablementState))); } - private getDependenciesAndPackedExtensionsRecursively(extensions: IExtension[], installed: IExtension[], enablementState: EnablementState, checked: IExtension[] = []): IExtension[] { + private getExtensionsRecursively(extensions: IExtension[], installed: IExtension[], enablementState: EnablementState, options: { dependencies: boolean, pack: boolean }, checked: IExtension[] = []): IExtension[] { const toCheck = extensions.filter(e => checked.indexOf(e) === -1); if (toCheck.length) { for (const extension of toCheck) { @@ -799,11 +806,15 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService, if (i.enablementState === enablementState) { return false; } - return i.type === LocalExtensionType.User && - extensions.some(extension => extension.dependencies.some(id => areSameExtensions({ id }, i)) || extension.extensionPack.some(id => areSameExtensions({ id }, i))); + return i.type === LocalExtensionType.User + && (options.dependencies || options.pack) + && extensions.some(extension => + (options.dependencies && extension.dependencies.some(id => areSameExtensions({ id }, i))) + || (options.pack && extension.extensionPack.some(id => areSameExtensions({ id }, i))) + ); }); if (extensionsToDisable.length) { - extensionsToDisable.push(...this.getDependenciesAndPackedExtensionsRecursively(extensionsToDisable, installed, enablementState, checked)); + extensionsToDisable.push(...this.getExtensionsRecursively(extensionsToDisable, installed, enablementState, options, checked)); } return extensionsToDisable; }