#146048 - Remove dependency on IExtensionManagementService - causing cycling dependencies

This commit is contained in:
Sandeep Somavarapu 2022-03-29 00:16:25 +05:30
parent 64f37bc300
commit 5a095df0d9
No known key found for this signature in database
GPG key ID: DD41CAAC8081CC7D
3 changed files with 49 additions and 45 deletions

View file

@ -5,10 +5,11 @@
import { Disposable } from 'vs/base/common/lifecycle';
import { IExtensionGalleryService, IExtensionManagementService, IGlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionStorageService } from 'vs/platform/extensionManagement/common/extensionStorage';
import { ExtensionStorageService, IExtensionStorageService } from 'vs/platform/extensionManagement/common/extensionStorage';
import { migrateUnsupportedExtensions } from 'vs/platform/extensionManagement/common/unsupportedExtensionsMigration';
import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService';
import { ILogService } from 'vs/platform/log/common/log';
import { IStorageService } from 'vs/platform/storage/common/storage';
export class ExtensionsCleaner extends Disposable {
@ -17,11 +18,12 @@ export class ExtensionsCleaner extends Disposable {
@IExtensionGalleryService extensionGalleryService: IExtensionGalleryService,
@IExtensionStorageService extensionStorageService: IExtensionStorageService,
@IGlobalExtensionEnablementService extensionEnablementService: IGlobalExtensionEnablementService,
@IStorageService storageService: IStorageService,
@ILogService logService: ILogService,
) {
super();
extensionManagementService.removeDeprecatedExtensions();
migrateUnsupportedExtensions(extensionManagementService, extensionGalleryService, extensionStorageService, extensionEnablementService, logService);
extensionStorageService.removeOutdatedExtensionVersions();
ExtensionStorageService.removeOutdatedExtensionVersions(extensionManagementService, storageService);
}
}

View file

@ -35,8 +35,6 @@ export interface IExtensionStorageService {
addToMigrationList(from: string, to: string): void;
getSourceExtensionToMigrate(target: string): string | undefined;
removeOutdatedExtensionVersions(): Promise<void>;
}
const EXTENSION_KEYS_ID_VERSION_REGEX = /^extensionKeys\/([^.]+\..+)@(\d+\.\d+\.\d+(-.*)?)$/;
@ -57,32 +55,53 @@ export class ExtensionStorageService extends Disposable implements IExtensionSto
return undefined;
}
static async removeOutdatedExtensionVersions(extensionManagementService: IExtensionManagementService, storageService: IStorageService): Promise<void> {
const extensions = await extensionManagementService.getInstalled();
const extensionVersionsToRemove: string[] = [];
for (const [id, versions] of ExtensionStorageService.readAllExtensionsWithKeysForSync(storageService)) {
const extensionVersion = extensions.find(e => areSameExtensions(e.identifier, { id }))?.manifest.version;
for (const version of versions) {
if (extensionVersion !== version) {
extensionVersionsToRemove.push(ExtensionStorageService.toKey({ id, version }));
}
}
}
for (const key of extensionVersionsToRemove) {
storageService.remove(key, StorageScope.GLOBAL);
}
}
private static readAllExtensionsWithKeysForSync(storageService: IStorageService): Map<string, string[]> {
const extensionsWithKeysForSync = new Map<string, string[]>();
const keys = storageService.keys(StorageScope.GLOBAL, StorageTarget.MACHINE);
for (const key of keys) {
const extensionIdWithVersion = ExtensionStorageService.fromKey(key);
if (extensionIdWithVersion) {
let versions = extensionsWithKeysForSync.get(extensionIdWithVersion.id.toLowerCase());
if (!versions) {
extensionsWithKeysForSync.set(extensionIdWithVersion.id.toLowerCase(), versions = []);
}
versions.push(extensionIdWithVersion.version);
}
}
return extensionsWithKeysForSync;
}
private readonly _onDidChangeExtensionStorageToSync = this._register(new Emitter<void>());
readonly onDidChangeExtensionStorageToSync = this._onDidChangeExtensionStorageToSync.event;
private readonly extensionsWithKeysForSync = new Map<string, string[]>();
private readonly extensionsWithKeysForSync: Map<string, string[]>;
constructor(
@IStorageService private readonly storageService: IStorageService,
@IProductService private readonly productService: IProductService,
@ILogService private readonly logService: ILogService,
@IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService,
) {
super();
this.initialize();
this.extensionsWithKeysForSync = ExtensionStorageService.readAllExtensionsWithKeysForSync(storageService);
this._register(this.storageService.onDidChangeValue(e => this.onDidChangeStorageValue(e)));
}
private initialize(): void {
const keys = this.storageService.keys(StorageScope.GLOBAL, StorageTarget.MACHINE);
for (const key of keys) {
const extensionIdWithVersion = ExtensionStorageService.fromKey(key);
if (extensionIdWithVersion) {
this.addExtensionIdWithVersionToCache(extensionIdWithVersion);
}
}
}
private onDidChangeStorageValue(e: IStorageValueChangeEvent): void {
if (e.scope !== StorageScope.GLOBAL) {
return;
@ -100,21 +119,17 @@ export class ExtensionStorageService extends Disposable implements IExtensionSto
if (this.storageService.get(e.key, StorageScope.GLOBAL) === undefined) {
this.extensionsWithKeysForSync.delete(extensionIdWithVersion.id.toLowerCase());
} else {
this.addExtensionIdWithVersionToCache(extensionIdWithVersion);
let versions = this.extensionsWithKeysForSync.get(extensionIdWithVersion.id.toLowerCase());
if (!versions) {
this.extensionsWithKeysForSync.set(extensionIdWithVersion.id.toLowerCase(), versions = []);
}
versions.push(extensionIdWithVersion.version);
this._onDidChangeExtensionStorageToSync.fire();
}
return;
}
}
private addExtensionIdWithVersionToCache(extensionIdWithVersion: IExtensionIdWithVersion) {
let versions = this.extensionsWithKeysForSync.get(extensionIdWithVersion.id.toLowerCase());
if (!versions) {
this.extensionsWithKeysForSync.set(extensionIdWithVersion.id.toLowerCase(), versions = []);
}
versions.push(extensionIdWithVersion.version);
}
private getExtensionId(extension: IExtension | IGalleryExtension | string): string {
if (isString(extension)) {
return extension;
@ -196,20 +211,4 @@ export class ExtensionStorageService extends Disposable implements IExtensionSto
}
}
async removeOutdatedExtensionVersions(): Promise<void> {
const extensions = await this.extensionManagementService.getInstalled();
const extensionVersionsToRemove: string[] = [];
for (const [id, versions] of this.extensionsWithKeysForSync) {
const extensionVersion = extensions.find(e => areSameExtensions(e.identifier, { id }))?.manifest.version;
for (const version of versions) {
if (extensionVersion !== version) {
extensionVersionsToRemove.push(ExtensionStorageService.toKey({ id, version }));
}
}
}
for (const key of extensionVersionsToRemove) {
this.extensionsWithKeysForSync.delete(key);
this.storageService.remove(key, StorageScope.GLOBAL);
}
}
}

View file

@ -3,14 +3,17 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IExtensionStorageService } from 'vs/platform/extensionManagement/common/extensionStorage';
import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ExtensionStorageService } from 'vs/platform/extensionManagement/common/extensionStorage';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
export class ExtensionsCleaner implements IWorkbenchContribution {
constructor(
@IExtensionStorageService extensionStorageService: IExtensionStorageService,
@IExtensionManagementService extensionManagementService: IExtensionManagementService,
@IStorageService storageService: IStorageService,
) {
extensionStorageService.removeOutdatedExtensionVersions();
ExtensionStorageService.removeOutdatedExtensionVersions(extensionManagementService, storageService);
}
}