Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/services/extensions/common/extensionStorageMigration.ts
3296 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 { getErrorMessage } from '../../../../base/common/errors.js';
7
import { URI } from '../../../../base/common/uri.js';
8
import { IEnvironmentService } from '../../../../platform/environment/common/environment.js';
9
import { IExtensionStorageService } from '../../../../platform/extensionManagement/common/extensionStorage.js';
10
import { FileSystemProviderError, FileSystemProviderErrorCode, IFileService } from '../../../../platform/files/common/files.js';
11
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
12
import { ILogService } from '../../../../platform/log/common/log.js';
13
import { IStorageService, StorageScope, StorageTarget } from '../../../../platform/storage/common/storage.js';
14
import { IUriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentity.js';
15
import { IUserDataProfilesService } from '../../../../platform/userDataProfile/common/userDataProfile.js';
16
import { IWorkspaceContextService } from '../../../../platform/workspace/common/workspace.js';
17
18
/**
19
* An extension storage has following
20
* - State: Stored using storage service with extension id as key and state as value.
21
* - Resources: Stored under a location scoped to the extension.
22
*/
23
export async function migrateExtensionStorage(fromExtensionId: string, toExtensionId: string, global: boolean, instantionService: IInstantiationService): Promise<void> {
24
return instantionService.invokeFunction(async serviceAccessor => {
25
const environmentService = serviceAccessor.get(IEnvironmentService);
26
const userDataProfilesService = serviceAccessor.get(IUserDataProfilesService);
27
const extensionStorageService = serviceAccessor.get(IExtensionStorageService);
28
const storageService = serviceAccessor.get(IStorageService);
29
const uriIdentityService = serviceAccessor.get(IUriIdentityService);
30
const fileService = serviceAccessor.get(IFileService);
31
const workspaceContextService = serviceAccessor.get(IWorkspaceContextService);
32
const logService = serviceAccessor.get(ILogService);
33
const storageMigratedKey = `extensionStorage.migrate.${fromExtensionId}-${toExtensionId}`;
34
const migrateLowerCaseStorageKey = fromExtensionId.toLowerCase() === toExtensionId.toLowerCase() ? `extension.storage.migrateFromLowerCaseKey.${fromExtensionId.toLowerCase()}` : undefined;
35
36
if (fromExtensionId === toExtensionId) {
37
return;
38
}
39
40
const getExtensionStorageLocation = (extensionId: string, global: boolean): URI => {
41
if (global) {
42
return uriIdentityService.extUri.joinPath(userDataProfilesService.defaultProfile.globalStorageHome, extensionId.toLowerCase() /* Extension id is lower cased for global storage */);
43
}
44
return uriIdentityService.extUri.joinPath(environmentService.workspaceStorageHome, workspaceContextService.getWorkspace().id, extensionId);
45
};
46
47
const storageScope = global ? StorageScope.PROFILE : StorageScope.WORKSPACE;
48
if (!storageService.getBoolean(storageMigratedKey, storageScope, false) && !(migrateLowerCaseStorageKey && storageService.getBoolean(migrateLowerCaseStorageKey, storageScope, false))) {
49
logService.info(`Migrating ${global ? 'global' : 'workspace'} extension storage from ${fromExtensionId} to ${toExtensionId}...`);
50
// Migrate state
51
const value = extensionStorageService.getExtensionState(fromExtensionId, global);
52
if (value) {
53
extensionStorageService.setExtensionState(toExtensionId, value, global);
54
extensionStorageService.setExtensionState(fromExtensionId, undefined, global);
55
}
56
57
// Migrate stored files
58
const fromPath = getExtensionStorageLocation(fromExtensionId, global);
59
const toPath = getExtensionStorageLocation(toExtensionId, global);
60
if (!uriIdentityService.extUri.isEqual(fromPath, toPath)) {
61
try {
62
await fileService.move(fromPath, toPath, true);
63
} catch (error) {
64
if ((<FileSystemProviderError>error).code !== FileSystemProviderErrorCode.FileNotFound) {
65
logService.info(`Error while migrating ${global ? 'global' : 'workspace'} file storage from '${fromExtensionId}' to '${toExtensionId}'`, getErrorMessage(error));
66
}
67
}
68
}
69
logService.info(`Migrated ${global ? 'global' : 'workspace'} extension storage from ${fromExtensionId} to ${toExtensionId}`);
70
storageService.store(storageMigratedKey, true, storageScope, StorageTarget.MACHINE);
71
}
72
});
73
}
74
75