Skip to content

Commit 1fe501f

Browse files
authored
show profiles data in sync data views (microsoft#164429)
1 parent 5a326b2 commit 1fe501f

17 files changed

+666
-401
lines changed

src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ import { ILocalPtyService } from 'vs/platform/terminal/electron-sandbox/terminal
7070
import { PtyHostService } from 'vs/platform/terminal/node/ptyHostService';
7171
import { ExtensionStorageService, IExtensionStorageService } from 'vs/platform/extensionManagement/common/extensionStorage';
7272
import { IgnoredExtensionsManagementService, IIgnoredExtensionsManagementService } from 'vs/platform/userDataSync/common/ignoredExtensions';
73-
import { IUserDataSyncBackupStoreService, IUserDataSyncLogService, IUserDataSyncEnablementService, IUserDataSyncService, IUserDataSyncStoreManagementService, IUserDataSyncStoreService, IUserDataSyncUtilService, registerConfiguration as registerUserDataSyncConfiguration } from 'vs/platform/userDataSync/common/userDataSync';
73+
import { IUserDataSyncBackupStoreService, IUserDataSyncLogService, IUserDataSyncEnablementService, IUserDataSyncService, IUserDataSyncStoreManagementService, IUserDataSyncStoreService, IUserDataSyncUtilService, registerConfiguration as registerUserDataSyncConfiguration, IUserDataSyncResourceProviderService } from 'vs/platform/userDataSync/common/userDataSync';
7474
import { IUserDataSyncAccountService, UserDataSyncAccountService } from 'vs/platform/userDataSync/common/userDataSyncAccount';
7575
import { UserDataSyncBackupStoreService } from 'vs/platform/userDataSync/common/userDataSyncBackupStoreService';
7676
import { UserDataAutoSyncChannel, UserDataSyncAccountServiceChannel, UserDataSyncMachinesServiceChannel, UserDataSyncStoreManagementServiceChannel, UserDataSyncUtilServiceClient } from 'vs/platform/userDataSync/common/userDataSyncIpc';
@@ -112,6 +112,7 @@ import { UserDataProfilesCleaner } from 'vs/code/electron-browser/sharedProcess/
112112
import { RemoteTunnelService } from 'vs/platform/remoteTunnel/electron-browser/remoteTunnelService';
113113
import { IRemoteTunnelService } from 'vs/platform/remoteTunnel/common/remoteTunnel';
114114
import { ISharedProcessLifecycleService, SharedProcessLifecycleService } from 'vs/platform/lifecycle/electron-browser/sharedProcessLifecycleService';
115+
import { UserDataSyncResourceProviderService } from 'vs/platform/userDataSync/common/userDataSyncResourceProvider';
115116

116117
class SharedProcessMain extends Disposable {
117118

@@ -361,6 +362,7 @@ class SharedProcessMain extends Disposable {
361362
services.set(IUserDataSyncEnablementService, new SyncDescriptor(UserDataSyncEnablementService, undefined, true));
362363
services.set(IUserDataSyncService, new SyncDescriptor(UserDataSyncService, undefined, false /* Initializes the Sync State */));
363364
services.set(IUserDataSyncProfilesStorageService, new SyncDescriptor(UserDataSyncProfilesStorageService, undefined, true));
365+
services.set(IUserDataSyncResourceProviderService, new SyncDescriptor(UserDataSyncResourceProviderService, undefined, true));
364366

365367
// Terminal
366368

src/vs/platform/userDataSync/common/abstractSynchronizer.ts

Lines changed: 7 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { FormattingOptions } from 'vs/base/common/jsonFormatter';
1414
import { Disposable } from 'vs/base/common/lifecycle';
1515
import { IExtUri } from 'vs/base/common/resources';
1616
import { uppercaseFirstLetter } from 'vs/base/common/strings';
17-
import { isString, isUndefined } from 'vs/base/common/types';
17+
import { isUndefined } from 'vs/base/common/types';
1818
import { URI } from 'vs/base/common/uri';
1919
import { IHeaders } from 'vs/base/parts/request/common/request';
2020
import { localize } from 'vs/nls';
@@ -26,7 +26,7 @@ import { getServiceMachineId } from 'vs/platform/externalServices/common/service
2626
import { IStorageService } from 'vs/platform/storage/common/storage';
2727
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
2828
import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity';
29-
import { Change, getLastSyncResourceUri, IRemoteUserData, IResourcePreview as IBaseResourcePreview, ISyncData, ISyncResourceHandle, IUserDataSyncResourcePreview as IBaseSyncResourcePreview, IUserData, IUserDataInitializer, IUserDataSyncBackupStoreService, IUserDataSyncConfiguration, IUserDataSynchroniser, IUserDataSyncLogService, IUserDataSyncEnablementService, IUserDataSyncStoreService, IUserDataSyncUtilService, MergeState, PREVIEW_DIR_NAME, SyncResource, SyncStatus, UserDataSyncError, UserDataSyncErrorCode, USER_DATA_SYNC_CONFIGURATION_SCOPE, USER_DATA_SYNC_SCHEME, IUserDataResourceManifest, getPathSegments, IUserDataSyncResourceConflicts, IUserDataSyncResource } from 'vs/platform/userDataSync/common/userDataSync';
29+
import { Change, getLastSyncResourceUri, IRemoteUserData, IResourcePreview as IBaseResourcePreview, ISyncData, IUserDataSyncResourcePreview as IBaseSyncResourcePreview, IUserData, IUserDataInitializer, IUserDataSyncBackupStoreService, IUserDataSyncConfiguration, IUserDataSynchroniser, IUserDataSyncLogService, IUserDataSyncEnablementService, IUserDataSyncStoreService, IUserDataSyncUtilService, MergeState, PREVIEW_DIR_NAME, SyncResource, SyncStatus, UserDataSyncError, UserDataSyncErrorCode, USER_DATA_SYNC_CONFIGURATION_SCOPE, USER_DATA_SYNC_SCHEME, IUserDataResourceManifest, getPathSegments, IUserDataSyncResourceConflicts, IUserDataSyncResource } from 'vs/platform/userDataSync/common/userDataSync';
3030
import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
3131

3232
type IncompatibleSyncSourceClassification = {
@@ -242,12 +242,7 @@ export abstract class AbstractSynchroniser extends Disposable implements IUserDa
242242
}
243243
}
244244

245-
async replace(uri: URI): Promise<boolean> {
246-
const content = await this.resolveContent(uri);
247-
if (!content) {
248-
return false;
249-
}
250-
245+
async replace(content: string): Promise<boolean> {
251246
const syncData = this.parseSyncData(content);
252247
if (!syncData) {
253248
return false;
@@ -490,48 +485,6 @@ export abstract class AbstractSynchroniser extends Disposable implements IUserDa
490485
return !!lastSyncData && lastSyncData.syncData !== null /* `null` sync data implies resource is not synced */;
491486
}
492487

493-
async getRemoteSyncResourceHandles(): Promise<ISyncResourceHandle[]> {
494-
const handles = await this.userDataSyncStoreService.getAllResourceRefs(this.resource, this.collection);
495-
return handles.map(({ created, ref }) => ({ created, uri: this.toRemoteBackupResource(ref) }));
496-
}
497-
498-
async getLocalSyncResourceHandles(): Promise<ISyncResourceHandle[]> {
499-
const handles = await this.userDataSyncBackupStoreService.getAllRefs(this.syncResource.profile, this.resource);
500-
return handles.map(({ created, ref }) => ({ created, uri: this.toLocalBackupResource(ref) }));
501-
}
502-
503-
private toRemoteBackupResource(ref: string): URI {
504-
return URI.from({ scheme: USER_DATA_SYNC_SCHEME, authority: 'remote-backup', path: `/${this.syncResource.profile.isDefault ? '' : `${this.syncResource.profile.id}/`}${this.resource}/${ref}` });
505-
}
506-
507-
private toLocalBackupResource(ref: string): URI {
508-
return URI.from({ scheme: USER_DATA_SYNC_SCHEME, authority: 'local-backup', path: `/${this.syncResource.profile.id}/${this.resource}/${ref}` });
509-
}
510-
511-
async getMachineId({ uri }: ISyncResourceHandle): Promise<string | undefined> {
512-
const ref = this.extUri.basename(uri);
513-
if (this.extUri.isEqual(uri, this.toRemoteBackupResource(ref))) {
514-
const { content } = await this.getUserData(ref);
515-
if (content) {
516-
const syncData = this.parseSyncData(content);
517-
return syncData?.machineId;
518-
}
519-
}
520-
return undefined;
521-
}
522-
523-
async resolveContent(uri: URI): Promise<string | null> {
524-
const ref = this.extUri.basename(uri);
525-
if (this.extUri.isEqual(uri, this.toRemoteBackupResource(ref))) {
526-
const { content } = await this.getUserData(ref);
527-
return content;
528-
}
529-
if (this.extUri.isEqual(uri, this.toLocalBackupResource(ref))) {
530-
return this.userDataSyncBackupStoreService.resolveContent(this.syncResource.profile, this.resource, ref);
531-
}
532-
return null;
533-
}
534-
535488
protected async resolvePreviewContent(uri: URI): Promise<string | null> {
536489
const syncPreview = this.syncPreviewPromise ? await this.syncPreviewPromise : null;
537490
if (syncPreview) {
@@ -670,14 +623,9 @@ export abstract class AbstractSynchroniser extends Disposable implements IUserDa
670623
throw new UserDataSyncError(localize('incompatible sync data', "Cannot parse sync data as it is not compatible with the current version."), UserDataSyncErrorCode.IncompatibleRemoteContent, this.resource);
671624
}
672625

673-
private async getUserData(refOrLastSyncData: string | IRemoteUserData | null): Promise<IUserData> {
674-
if (isString(refOrLastSyncData)) {
675-
const content = await this.userDataSyncStoreService.resolveResourceContent(this.resource, refOrLastSyncData, this.collection);
676-
return { ref: refOrLastSyncData, content };
677-
} else {
678-
const lastSyncUserData: IUserData | null = refOrLastSyncData ? { ref: refOrLastSyncData.ref, content: refOrLastSyncData.syncData ? JSON.stringify(refOrLastSyncData.syncData) : null } : null;
679-
return this.userDataSyncStoreService.readResource(this.resource, lastSyncUserData, this.collection, this.syncHeaders);
680-
}
626+
private async getUserData(lastSyncData: IRemoteUserData | null): Promise<IUserData> {
627+
const lastSyncUserData: IUserData | null = lastSyncData ? { ref: lastSyncData.ref, content: lastSyncData.syncData ? JSON.stringify(lastSyncData.syncData) : null } : null;
628+
return this.userDataSyncStoreService.readResource(this.resource, lastSyncUserData, this.collection, this.syncHeaders);
681629
}
682630

683631
protected async updateRemoteUserData(content: string, ref: string | null): Promise<IRemoteUserData> {
@@ -729,7 +677,7 @@ export abstract class AbstractSynchroniser extends Disposable implements IUserDa
729677
protected abstract hasRemoteChanged(lastSyncUserData: IRemoteUserData): Promise<boolean>;
730678

731679
abstract hasLocalData(): Promise<boolean>;
732-
abstract getAssociatedResources(syncResourceHandle: ISyncResourceHandle): Promise<{ resource: URI; comparableResource: URI }[]>;
680+
abstract resolveContent(uri: URI): Promise<string | null>;
733681
}
734682

735683
export interface IFileResourcePreview extends IResourcePreview {

src/vs/platform/userDataSync/common/extensionsSync.ts

Lines changed: 20 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userData
3030
import { AbstractInitializer, AbstractSynchroniser, getSyncResourceLogLabel, IAcceptResult, IMergeResult, IResourcePreview } from 'vs/platform/userDataSync/common/abstractSynchronizer';
3131
import { IMergeResult as IExtensionMergeResult, merge } from 'vs/platform/userDataSync/common/extensionsMerge';
3232
import { IIgnoredExtensionsManagementService } from 'vs/platform/userDataSync/common/ignoredExtensions';
33-
import { Change, IRemoteUserData, ISyncData, ISyncExtension, ISyncExtensionWithVersion, ISyncResourceHandle, IUserDataSyncBackupStoreService, IUserDataSynchroniser, IUserDataSyncLogService, IUserDataSyncEnablementService, IUserDataSyncStoreService, SyncResource, USER_DATA_SYNC_SCHEME } from 'vs/platform/userDataSync/common/userDataSync';
33+
import { Change, IRemoteUserData, ISyncData, ISyncExtension, ISyncExtensionWithVersion, IUserDataSyncBackupStoreService, IUserDataSynchroniser, IUserDataSyncLogService, IUserDataSyncEnablementService, IUserDataSyncStoreService, SyncResource, USER_DATA_SYNC_SCHEME } from 'vs/platform/userDataSync/common/userDataSync';
3434
import { IUserDataSyncProfilesStorageService } from 'vs/platform/userDataSync/common/userDataSyncProfilesStorageService';
3535

3636
type IExtensionResourceMergeResult = IAcceptResult & IExtensionMergeResult;
@@ -76,9 +76,24 @@ async function parseAndMigrateExtensions(syncData: ISyncData, extensionManagemen
7676
return extensions;
7777
}
7878

79-
export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUserDataSynchroniser {
79+
export function parseExtensions(syncData: ISyncData): ISyncExtension[] {
80+
return JSON.parse(syncData.content);
81+
}
82+
83+
export function stringify(extensions: ISyncExtension[], format: boolean): string {
84+
extensions.sort((e1, e2) => {
85+
if (!e1.identifier.uuid && e2.identifier.uuid) {
86+
return -1;
87+
}
88+
if (e1.identifier.uuid && !e2.identifier.uuid) {
89+
return 1;
90+
}
91+
return compare(e1.identifier.id, e2.identifier.id);
92+
});
93+
return format ? toFormattedString(extensions, {}) : JSON.stringify(extensions);
94+
}
8095

81-
private static readonly EXTENSIONS_DATA_URI = URI.from({ scheme: USER_DATA_SYNC_SCHEME, authority: 'extensions', path: `/extensions.json` });
96+
export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUserDataSynchroniser {
8297

8398
/*
8499
Version 3 - Introduce installed property to skip installing built in extensions
@@ -292,16 +307,7 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse
292307
}
293308
}
294309

295-
async getAssociatedResources({ uri }: ISyncResourceHandle): Promise<{ resource: URI; comparableResource: URI }[]> {
296-
return [{ resource: this.extUri.joinPath(uri, 'extensions.json'), comparableResource: ExtensionsSynchroniser.EXTENSIONS_DATA_URI }];
297-
}
298-
299-
override async resolveContent(uri: URI): Promise<string | null> {
300-
if (this.extUri.isEqual(uri, ExtensionsSynchroniser.EXTENSIONS_DATA_URI)) {
301-
const { localExtensions, ignoredExtensions } = await this.localExtensionsProvider.getLocalExtensions(this.profile);
302-
return this.stringify(localExtensions.filter(e => !ignoredExtensions.some(id => areSameExtensions({ id }, e.identifier))), true);
303-
}
304-
310+
async resolveContent(uri: URI): Promise<string | null> {
305311
if (this.extUri.isEqual(this.remoteResource, uri)
306312
|| this.extUri.isEqual(this.baseResource, uri)
307313
|| this.extUri.isEqual(this.localResource, uri)
@@ -310,37 +316,11 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse
310316
const content = await this.resolvePreviewContent(uri);
311317
return content ? this.stringify(JSON.parse(content), true) : content;
312318
}
313-
314-
let content = await super.resolveContent(uri);
315-
if (content) {
316-
return content;
317-
}
318-
319-
content = await super.resolveContent(this.extUri.dirname(uri));
320-
if (content) {
321-
const syncData = this.parseSyncData(content);
322-
if (syncData) {
323-
switch (this.extUri.basename(uri)) {
324-
case 'extensions.json':
325-
return this.stringify(this.parseExtensions(syncData), true);
326-
}
327-
}
328-
}
329-
330319
return null;
331320
}
332321

333322
private stringify(extensions: ISyncExtension[], format: boolean): string {
334-
extensions.sort((e1, e2) => {
335-
if (!e1.identifier.uuid && e2.identifier.uuid) {
336-
return -1;
337-
}
338-
if (e1.identifier.uuid && !e2.identifier.uuid) {
339-
return 1;
340-
}
341-
return compare(e1.identifier.id, e2.identifier.id);
342-
});
343-
return format ? toFormattedString(extensions, {}) : JSON.stringify(extensions);
323+
return stringify(extensions, format);
344324
}
345325

346326
async hasLocalData(): Promise<boolean> {
@@ -355,10 +335,6 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse
355335
return false;
356336
}
357337

358-
private parseExtensions(syncData: ISyncData): ISyncExtension[] {
359-
return JSON.parse(syncData.content);
360-
}
361-
362338
}
363339

364340
export class LocalExtensionsProvider {

src/vs/platform/userDataSync/common/globalStateSync.ts

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'
2525
import { AbstractInitializer, AbstractSynchroniser, getSyncResourceLogLabel, IAcceptResult, IMergeResult, IResourcePreview, isSyncData } from 'vs/platform/userDataSync/common/abstractSynchronizer';
2626
import { edit } from 'vs/platform/userDataSync/common/content';
2727
import { merge } from 'vs/platform/userDataSync/common/globalStateMerge';
28-
import { ALL_SYNC_RESOURCES, Change, createSyncHeaders, getEnablementKey, IGlobalState, IRemoteUserData, IStorageValue, ISyncData, ISyncResourceHandle, IUserData, IUserDataSyncBackupStoreService, IUserDataSynchroniser, IUserDataSyncLogService, IUserDataSyncEnablementService, IUserDataSyncStoreService, SyncResource, SYNC_SERVICE_URL_TYPE, UserDataSyncError, UserDataSyncErrorCode, UserDataSyncStoreType, USER_DATA_SYNC_SCHEME } from 'vs/platform/userDataSync/common/userDataSync';
28+
import { ALL_SYNC_RESOURCES, Change, createSyncHeaders, getEnablementKey, IGlobalState, IRemoteUserData, IStorageValue, ISyncData, IUserData, IUserDataSyncBackupStoreService, IUserDataSynchroniser, IUserDataSyncLogService, IUserDataSyncEnablementService, IUserDataSyncStoreService, SyncResource, SYNC_SERVICE_URL_TYPE, UserDataSyncError, UserDataSyncErrorCode, UserDataSyncStoreType, USER_DATA_SYNC_SCHEME } from 'vs/platform/userDataSync/common/userDataSync';
2929
import { UserDataSyncStoreClient } from 'vs/platform/userDataSync/common/userDataSyncStoreService';
3030
import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
3131
import { IUserDataSyncProfilesStorageService } from 'vs/platform/userDataSync/common/userDataSyncProfilesStorageService';
@@ -47,7 +47,7 @@ export interface IGlobalStateResourcePreview extends IResourcePreview {
4747
readonly storageKeys: StorageKeys;
4848
}
4949

50-
function stringify(globalState: IGlobalState, format: boolean): string {
50+
export function stringify(globalState: IGlobalState, format: boolean): string {
5151
const storageKeys = globalState.storage ? Object.keys(globalState.storage).sort() : [];
5252
const storage: IStringDictionary<IStorageValue> = {};
5353
storageKeys.forEach(key => storage[key] = globalState.storage[key]);
@@ -68,7 +68,6 @@ const GLOBAL_STATE_DATA_VERSION = 1;
6868
*/
6969
export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUserDataSynchroniser {
7070

71-
private static readonly GLOBAL_STATE_DATA_URI = URI.from({ scheme: USER_DATA_SYNC_SCHEME, authority: 'globalState', path: `/globalState.json` });
7271
protected readonly version: number = GLOBAL_STATE_DATA_VERSION;
7372
private readonly previewResource: URI = this.extUri.joinPath(this.syncPreviewFolder, 'globalState.json');
7473
private readonly baseResource: URI = this.previewResource.with({ scheme: USER_DATA_SYNC_SCHEME, authority: 'base' });
@@ -258,16 +257,7 @@ export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUs
258257
}
259258
}
260259

261-
async getAssociatedResources({ uri }: ISyncResourceHandle): Promise<{ resource: URI; comparableResource: URI }[]> {
262-
return [{ resource: this.extUri.joinPath(uri, 'globalState.json'), comparableResource: GlobalStateSynchroniser.GLOBAL_STATE_DATA_URI }];
263-
}
264-
265-
override async resolveContent(uri: URI): Promise<string | null> {
266-
if (this.extUri.isEqual(uri, GlobalStateSynchroniser.GLOBAL_STATE_DATA_URI)) {
267-
const localGlobalState = await this.localGlobalStateProvider.getLocalGlobalState(this.syncResource.profile);
268-
return stringify(localGlobalState, true);
269-
}
270-
260+
async resolveContent(uri: URI): Promise<string | null> {
271261
if (this.extUri.isEqual(this.remoteResource, uri)
272262
|| this.extUri.isEqual(this.baseResource, uri)
273263
|| this.extUri.isEqual(this.localResource, uri)
@@ -276,23 +266,6 @@ export class GlobalStateSynchroniser extends AbstractSynchroniser implements IUs
276266
const content = await this.resolvePreviewContent(uri);
277267
return content ? stringify(JSON.parse(content), true) : content;
278268
}
279-
280-
let content = await super.resolveContent(uri);
281-
if (content) {
282-
return content;
283-
}
284-
285-
content = await super.resolveContent(this.extUri.dirname(uri));
286-
if (content) {
287-
const syncData = this.parseSyncData(content);
288-
if (syncData) {
289-
switch (this.extUri.basename(uri)) {
290-
case 'globalState.json':
291-
return stringify(JSON.parse(syncData.content), true);
292-
}
293-
}
294-
}
295-
296269
return null;
297270
}
298271

0 commit comments

Comments
 (0)