Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/platform/extensionManagement/common/unsupportedExtensionsMigration.ts
5251 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { CancellationToken } from '../../../base/common/cancellation.js';
7
import { EXTENSION_INSTALL_SKIP_PUBLISHER_TRUST_CONTEXT, IExtensionGalleryService, IExtensionManagementService, IGlobalExtensionEnablementService, InstallOperation } from './extensionManagement.js';
8
import { areSameExtensions, getExtensionId } from './extensionManagementUtil.js';
9
import { IExtensionStorageService } from './extensionStorage.js';
10
import { ExtensionType } from '../../extensions/common/extensions.js';
11
import { ILogService } from '../../log/common/log.js';
12
import * as semver from '../../../base/common/semver/semver.js';
13
import { IUserDataProfile } from '../../userDataProfile/common/userDataProfile.js';
14
15
/**
16
* Migrates the installed unsupported nightly extension to a supported pre-release extension. It includes following:
17
* - Uninstall the Unsupported extension
18
* - Install (with optional storage migration) the Pre-release extension only if
19
* - the extension is not installed
20
* - or it is a release version and the unsupported extension is enabled.
21
*/
22
export async function migrateUnsupportedExtensions(profile: IUserDataProfile | undefined, extensionManagementService: IExtensionManagementService, galleryService: IExtensionGalleryService, extensionStorageService: IExtensionStorageService, extensionEnablementService: IGlobalExtensionEnablementService, logService: ILogService): Promise<void> {
23
try {
24
const extensionsControlManifest = await extensionManagementService.getExtensionsControlManifest();
25
if (!extensionsControlManifest.deprecated) {
26
return;
27
}
28
const installed = await extensionManagementService.getInstalled(ExtensionType.User, profile?.extensionsResource);
29
for (const [unsupportedExtensionId, deprecated] of Object.entries(extensionsControlManifest.deprecated)) {
30
if (!deprecated?.extension) {
31
continue;
32
}
33
const { id: preReleaseExtensionId, autoMigrate, preRelease } = deprecated.extension;
34
if (!autoMigrate) {
35
continue;
36
}
37
const unsupportedExtension = installed.find(i => areSameExtensions(i.identifier, { id: unsupportedExtensionId }));
38
// Unsupported Extension is not installed
39
if (!unsupportedExtension) {
40
continue;
41
}
42
43
const gallery = (await galleryService.getExtensions([{ id: preReleaseExtensionId, preRelease }], { targetPlatform: await extensionManagementService.getTargetPlatform(), compatible: true }, CancellationToken.None))[0];
44
if (!gallery) {
45
logService.info(`Skipping migrating '${unsupportedExtension.identifier.id}' extension because, the comaptible target '${preReleaseExtensionId}' extension is not found`);
46
continue;
47
}
48
49
try {
50
logService.info(`Migrating '${unsupportedExtension.identifier.id}' extension to '${preReleaseExtensionId}' extension...`);
51
52
const isUnsupportedExtensionEnabled = !extensionEnablementService.getDisabledExtensions().some(e => areSameExtensions(e, unsupportedExtension.identifier));
53
await extensionManagementService.uninstall(unsupportedExtension, { profileLocation: profile?.extensionsResource });
54
logService.info(`Uninstalled the unsupported extension '${unsupportedExtension.identifier.id}'`);
55
56
let preReleaseExtension = installed.find(i => areSameExtensions(i.identifier, { id: preReleaseExtensionId }));
57
if (!preReleaseExtension || (preReleaseExtension.isPreReleaseVersion !== !!preRelease && isUnsupportedExtensionEnabled)) {
58
preReleaseExtension = await extensionManagementService.installFromGallery(gallery, { installPreReleaseVersion: preRelease, isMachineScoped: unsupportedExtension.isMachineScoped, operation: InstallOperation.Migrate, profileLocation: profile?.extensionsResource, context: { [EXTENSION_INSTALL_SKIP_PUBLISHER_TRUST_CONTEXT]: true } });
59
logService.info(`Installed the pre-release extension '${preReleaseExtension.identifier.id}'`);
60
if (!autoMigrate.donotDisable && !isUnsupportedExtensionEnabled) {
61
await extensionEnablementService.disableExtension(preReleaseExtension.identifier);
62
logService.info(`Disabled the pre-release extension '${preReleaseExtension.identifier.id}' because the unsupported extension '${unsupportedExtension.identifier.id}' is disabled`);
63
}
64
if (autoMigrate.storage) {
65
extensionStorageService.addToMigrationList(getExtensionId(unsupportedExtension.manifest.publisher, unsupportedExtension.manifest.name), getExtensionId(preReleaseExtension.manifest.publisher, preReleaseExtension.manifest.name));
66
logService.info(`Added pre-release extension to the storage migration list`);
67
}
68
}
69
logService.info(`Migrated '${unsupportedExtension.identifier.id}' extension to '${preReleaseExtensionId}' extension.`);
70
} catch (error) {
71
logService.error(error);
72
}
73
}
74
75
if (extensionsControlManifest.autoUpdate) {
76
for (const [extensionId, version] of Object.entries(extensionsControlManifest.autoUpdate)) {
77
try {
78
const extensionToAutoUpdate = installed.find(i => areSameExtensions(i.identifier, { id: extensionId }) && semver.lte(i.manifest.version, version));
79
if (!extensionToAutoUpdate) {
80
continue;
81
}
82
83
const gallery = (await galleryService.getExtensions([{ id: extensionId, preRelease: extensionToAutoUpdate.preRelease }], { targetPlatform: await extensionManagementService.getTargetPlatform(), compatible: true }, CancellationToken.None))[0];
84
if (!gallery) {
85
logService.info(`Skipping updating '${extensionToAutoUpdate.identifier.id}' extension because, the compatible target '${extensionId}' extension is not found`);
86
continue;
87
}
88
89
await extensionManagementService.installFromGallery(gallery, { installPreReleaseVersion: extensionToAutoUpdate.preRelease, isMachineScoped: extensionToAutoUpdate.isMachineScoped, operation: InstallOperation.Update, profileLocation: profile?.extensionsResource, context: { [EXTENSION_INSTALL_SKIP_PUBLISHER_TRUST_CONTEXT]: true } });
90
logService.info(`Autoupdated '${extensionToAutoUpdate.identifier.id}' extension to '${gallery.version}' extension.`);
91
} catch (error) {
92
logService.error(error);
93
}
94
}
95
}
96
97
} catch (error) {
98
logService.error(error);
99
}
100
}
101
102