Path: blob/main/src/vs/workbench/contrib/extensions/browser/extensionsDependencyChecker.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { IExtensionsWorkbenchService } from '../common/extensions.js';6import { IWorkbenchContribution } from '../../../common/contributions.js';7import { IExtensionService } from '../../../services/extensions/common/extensions.js';8import { CommandsRegistry } from '../../../../platform/commands/common/commands.js';9import { MenuRegistry, MenuId } from '../../../../platform/actions/common/actions.js';10import { localize } from '../../../../nls.js';11import { areSameExtensions } from '../../../../platform/extensionManagement/common/extensionManagementUtil.js';12import { INotificationService, Severity } from '../../../../platform/notification/common/notification.js';13import { Action } from '../../../../base/common/actions.js';14import { IHostService } from '../../../services/host/browser/host.js';15import { Disposable } from '../../../../base/common/lifecycle.js';16import { CancellationToken } from '../../../../base/common/cancellation.js';17import { Promises } from '../../../../base/common/async.js';1819export class ExtensionDependencyChecker extends Disposable implements IWorkbenchContribution {2021constructor(22@IExtensionService private readonly extensionService: IExtensionService,23@IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,24@INotificationService private readonly notificationService: INotificationService,25@IHostService private readonly hostService: IHostService26) {27super();28CommandsRegistry.registerCommand('workbench.extensions.installMissingDependencies', () => this.installMissingDependencies());29MenuRegistry.appendMenuItem(MenuId.CommandPalette, {30command: {31id: 'workbench.extensions.installMissingDependencies',32category: localize('extensions', "Extensions"),33title: localize('auto install missing deps', "Install Missing Dependencies")34}35});36}3738private async getUninstalledMissingDependencies(): Promise<string[]> {39const allMissingDependencies = await this.getAllMissingDependencies();40const localExtensions = await this.extensionsWorkbenchService.queryLocal();41return allMissingDependencies.filter(id => localExtensions.every(l => !areSameExtensions(l.identifier, { id })));42}4344private async getAllMissingDependencies(): Promise<string[]> {45await this.extensionService.whenInstalledExtensionsRegistered();46const runningExtensionsIds: Set<string> = this.extensionService.extensions.reduce((result, r) => { result.add(r.identifier.value.toLowerCase()); return result; }, new Set<string>());47const missingDependencies: Set<string> = new Set<string>();48for (const extension of this.extensionService.extensions) {49if (extension.extensionDependencies) {50extension.extensionDependencies.forEach(dep => {51if (!runningExtensionsIds.has(dep.toLowerCase())) {52missingDependencies.add(dep);53}54});55}56}57return [...missingDependencies.values()];58}5960private async installMissingDependencies(): Promise<void> {61const missingDependencies = await this.getUninstalledMissingDependencies();62if (missingDependencies.length) {63const extensions = await this.extensionsWorkbenchService.getExtensions(missingDependencies.map(id => ({ id })), CancellationToken.None);64if (extensions.length) {65await Promises.settled(extensions.map(extension => this.extensionsWorkbenchService.install(extension)));66this.notificationService.notify({67severity: Severity.Info,68message: localize('finished installing missing deps', "Finished installing missing dependencies. Please reload the window now."),69actions: {70primary: [new Action('realod', localize('reload', "Reload Window"), '', true,71() => this.hostService.reload())]72}73});74}75} else {76this.notificationService.info(localize('no missing deps', "There are no missing dependencies to install."));77}78}79}808182