Skip to content

Commit 4dd562c

Browse files
authored
Fix gaps in updating the profile (microsoft#188050)
microsoft#156144 Fix gaps in updating the profile
1 parent 31f7511 commit 4dd562c

File tree

22 files changed

+294
-287
lines changed

22 files changed

+294
-287
lines changed

src/vs/platform/userDataProfile/common/userDataProfile.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf
365365
throw new Error(`Profile '${profileToUpdate.name}' does not exist`);
366366
}
367367

368-
profile = toUserDataProfile(profile.id, options.name ?? profile.name, profile.location, this.profilesCacheHome, { shortName: options.shortName ?? profile.shortName, transient: options.transient ?? profile.isTransient, useDefaultFlags: options.useDefaultFlags ?? profile.useDefaultFlags });
368+
profile = toUserDataProfile(profile.id, options.name ?? profile.name, profile.location, this.profilesCacheHome, { shortName: options.shortName ?? profile.shortName, transient: options.transient ?? profile.isTransient, useDefaultFlags: options.useDefaultFlags ?? profile.useDefaultFlags }, this.defaultProfile);
369369
this.updateProfiles([], [], [profile]);
370370

371371
return profile;

src/vs/platform/userDataProfile/test/common/userDataProfileService.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,4 +226,13 @@ suite('UserDataProfileService (Common)', () => {
226226
assert.strictEqual(profile.extensionsResource.toString(), testObject.defaultProfile.extensionsResource.toString());
227227
});
228228

229+
test('update profile using default profile for keybindings', async () => {
230+
let profile = await testObject.createNamedProfile('name');
231+
profile = await testObject.updateProfile(profile, { useDefaultFlags: { keybindings: true } });
232+
233+
assert.strictEqual(profile.isDefault, false);
234+
assert.deepStrictEqual(profile.useDefaultFlags, { keybindings: true });
235+
assert.strictEqual(profile.keybindingsResource.toString(), testObject.defaultProfile.keybindingsResource.toString());
236+
});
237+
229238
});

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { IUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile';
6+
import { equals } from 'vs/base/common/objects';
7+
import { IUserDataProfile, UseDefaultProfileFlags } from 'vs/platform/userDataProfile/common/userDataProfile';
78
import { ISyncUserDataProfile } from 'vs/platform/userDataSync/common/userDataSync';
89

910
interface IRelaxedMergeResult {
@@ -17,6 +18,7 @@ interface IUserDataProfileInfo {
1718
readonly id: string;
1819
readonly name: string;
1920
readonly shortName?: string;
21+
readonly useDefaultFlags?: UseDefaultProfileFlags;
2022
}
2123

2224
export function merge(local: IUserDataProfile[], remote: ISyncUserDataProfile[] | null, lastSync: ISyncUserDataProfile[] | null, ignored: string[]): IMergeResult {
@@ -117,14 +119,15 @@ function compare(from: IUserDataProfileInfo[] | null, to: IUserDataProfileInfo[]
117119
const removed = fromKeys.filter(key => !toKeys.includes(key));
118120
const updated: string[] = [];
119121

120-
for (const { id, name, shortName } of from) {
122+
for (const { id, name, shortName, useDefaultFlags } of from) {
121123
if (removed.includes(id)) {
122124
continue;
123125
}
124126
const toProfile = to.find(p => p.id === id);
125127
if (!toProfile
126128
|| toProfile.name !== name
127129
|| toProfile.shortName !== shortName
130+
|| !equals(toProfile.useDefaultFlags, useDefaultFlags)
128131
) {
129132
updated.push(id);
130133
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ export class UserDataProfilesManifestSynchroniser extends AbstractSynchroniser i
206206
if (localProfile) {
207207
promises.push((async () => {
208208
this.logService.trace(`${this.syncResourceLogLabel}: Updating '${profile.name}' profile...`);
209-
await this.userDataProfilesService.updateProfile(localProfile, { name: profile.name, shortName: profile.shortName });
209+
await this.userDataProfilesService.updateProfile(localProfile, { name: profile.name, shortName: profile.shortName, useDefaultFlags: profile.useDefaultFlags });
210210
this.logService.info(`${this.syncResourceLogLabel}: Updated profile '${profile.name}'.`);
211211
})());
212212
} else {

src/vs/platform/userDataSync/test/common/userDataProfilesManifestMerge.test.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ suite('UserDataProfilesManifestMerge', () => {
7171
toUserDataProfile('5', '5', URI.file('5'), URI.file('cache')),
7272
toUserDataProfile('6', '6', URI.file('6'), URI.file('cache')),
7373
toUserDataProfile('8', '8', URI.file('8'), URI.file('cache')),
74+
toUserDataProfile('10', '10', URI.file('8'), URI.file('cache'), { useDefaultFlags: { tasks: true } }),
75+
toUserDataProfile('11', '11', URI.file('1'), URI.file('cache'), { useDefaultFlags: { keybindings: true } }),
7476
];
7577
const base: ISyncUserDataProfile[] = [
7678
{ id: '1', name: '1', collection: '1' },
@@ -79,6 +81,8 @@ suite('UserDataProfilesManifestMerge', () => {
7981
{ id: '4', name: '4', collection: '4' },
8082
{ id: '5', name: '5', collection: '5' },
8183
{ id: '6', name: '6', collection: '6' },
84+
{ id: '10', name: '10', collection: '10', useDefaultFlags: { tasks: true } },
85+
{ id: '11', name: '11', collection: '11' },
8286
];
8387
const remoteProfiles: ISyncUserDataProfile[] = [
8488
{ id: '1', name: '1', collection: '1' },
@@ -87,15 +91,18 @@ suite('UserDataProfilesManifestMerge', () => {
8791
{ id: '4', name: 'changed remote', collection: '4' },
8892
{ id: '5', name: '5', collection: '5' },
8993
{ id: '7', name: '7', collection: '7' },
94+
{ id: '9', name: '9', collection: '9', useDefaultFlags: { snippets: true } },
95+
{ id: '10', name: '10', collection: '10' },
96+
{ id: '11', name: '11', collection: '11' },
9097
];
9198

9299
const actual = merge(localProfiles, remoteProfiles, base, []);
93100

94-
assert.deepStrictEqual(actual.local.added, [remoteProfiles[5]]);
101+
assert.deepStrictEqual(actual.local.added, [remoteProfiles[5], remoteProfiles[6]]);
95102
assert.deepStrictEqual(actual.local.removed, [localProfiles[4]]);
96-
assert.deepStrictEqual(actual.local.updated, [remoteProfiles[2], remoteProfiles[3]]);
103+
assert.deepStrictEqual(actual.local.updated, [remoteProfiles[2], remoteProfiles[3], remoteProfiles[7]]);
97104
assert.deepStrictEqual(actual.remote?.added, [localProfiles[5]]);
98-
assert.deepStrictEqual(actual.remote?.updated, [localProfiles[0]]);
105+
assert.deepStrictEqual(actual.remote?.updated, [localProfiles[0], localProfiles[7]]);
99106
assert.deepStrictEqual(actual.remote?.removed, [remoteProfiles[1]]);
100107
});
101108

src/vs/platform/userDataSync/test/common/userDataProfilesManifestSync.test.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,47 @@ suite('UserDataProfilesManifestSync', () => {
217217
assert.deepStrictEqual(getLocalProfiles(testClient), [{ id: '1', name: 'name 1', shortName: undefined, useDefaultFlags: { keybindings: true } }]);
218218
});
219219

220+
test('sync profile when the profile is updated to use default profile locally', async () => {
221+
await client2.instantiationService.get(IUserDataProfilesService).createProfile('1', 'name 1');
222+
await client2.sync();
223+
224+
await testObject.sync(await testClient.getResourceManifest());
225+
226+
const profile = testClient.instantiationService.get(IUserDataProfilesService).profiles.find(p => p.id === '1')!;
227+
testClient.instantiationService.get(IUserDataProfilesService).updateProfile(profile, { useDefaultFlags: { keybindings: true } });
228+
229+
await testObject.sync(await testClient.getResourceManifest());
230+
assert.strictEqual(testObject.status, SyncStatus.Idle);
231+
assert.deepStrictEqual(testObject.conflicts.conflicts, []);
232+
233+
const { content } = await testClient.read(testObject.resource);
234+
assert.ok(content !== null);
235+
const actual = parseRemoteProfiles(content!);
236+
assert.deepStrictEqual(actual, [{ id: '1', name: 'name 1', collection: '1', useDefaultFlags: { keybindings: true } }]);
237+
assert.deepStrictEqual(getLocalProfiles(testClient), [{ id: '1', name: 'name 1', shortName: undefined, useDefaultFlags: { keybindings: true } }]);
238+
});
239+
240+
test('sync profile when the profile is updated to use default profile remotely', async () => {
241+
const profile = await client2.instantiationService.get(IUserDataProfilesService).createProfile('1', 'name 1');
242+
await client2.sync();
243+
244+
await testObject.sync(await testClient.getResourceManifest());
245+
246+
client2.instantiationService.get(IUserDataProfilesService).updateProfile(profile, { useDefaultFlags: { keybindings: true } });
247+
await client2.sync();
248+
249+
await testObject.sync(await testClient.getResourceManifest());
250+
assert.strictEqual(testObject.status, SyncStatus.Idle);
251+
assert.deepStrictEqual(testObject.conflicts.conflicts, []);
252+
253+
const { content } = await testClient.read(testObject.resource);
254+
assert.ok(content !== null);
255+
const actual = parseRemoteProfiles(content!);
256+
assert.deepStrictEqual(actual, [{ id: '1', name: 'name 1', collection: '1', useDefaultFlags: { keybindings: true } }]);
257+
258+
assert.deepStrictEqual(getLocalProfiles(testClient), [{ id: '1', name: 'name 1', shortName: undefined, useDefaultFlags: { keybindings: true } }]);
259+
});
260+
220261
function parseRemoteProfiles(content: string): ISyncUserDataProfile[] {
221262
const syncData: ISyncData = JSON.parse(content);
222263
return JSON.parse(syncData.content);

src/vs/workbench/browser/parts/activitybar/activitybarActions.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { EventType, addDisposableListener, EventHelper, append, $, clearNode, hi
99
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
1010
import { EventType as TouchEventType, GestureEvent } from 'vs/base/browser/touch';
1111
import { Action, IAction, Separator, SubmenuAction, toAction } from 'vs/base/common/actions';
12-
import { Event } from 'vs/base/common/event';
1312
import { KeyCode } from 'vs/base/common/keyCodes';
1413
import { DisposableStore } from 'vs/base/common/lifecycle';
1514
import { IMenuService, MenuId, IMenu, registerAction2, Action2, IAction2Options } from 'vs/platform/actions/common/actions';
@@ -485,7 +484,7 @@ export class GlobalActivityActionViewItem extends MenuActivityActionViewItem {
485484
@IKeybindingService keybindingService: IKeybindingService,
486485
) {
487486
super(MenuId.GlobalActivity, action, contextMenuActionsProvider, true, colors, activityHoverOptions, themeService, hoverService, menuService, contextMenuService, contextKeyService, configurationService, environmentService, keybindingService);
488-
this._register(Event.any(this.userDataProfileService.onDidUpdateCurrentProfile, this.userDataProfileService.onDidChangeCurrentProfile)(() => this.updateProfileBadge()));
487+
this._register(this.userDataProfileService.onDidChangeCurrentProfile(() => this.updateProfileBadge()));
489488
}
490489

491490
override render(container: HTMLElement): void {

src/vs/workbench/browser/parts/titlebar/windowTitle.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ export class WindowTitle extends Disposable {
7676
this._register(this.contextService.onDidChangeWorkspaceName(() => this.titleUpdater.schedule()));
7777
this._register(this.labelService.onDidChangeFormatters(() => this.titleUpdater.schedule()));
7878
this._register(this.userDataProfileService.onDidChangeCurrentProfile(() => this.titleUpdater.schedule()));
79-
this._register(this.userDataProfileService.onDidUpdateCurrentProfile(() => this.titleUpdater.schedule()));
8079
}
8180

8281
private onConfigurationChanged(event: IConfigurationChangeEvent): void {

src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ import { IStorageService } from 'vs/platform/storage/common/storage';
7878
import { IStringDictionary } from 'vs/base/common/collections';
7979
import { CONTEXT_KEYBINDINGS_EDITOR } from 'vs/workbench/contrib/preferences/common/preferences';
8080
import { DeprecatedExtensionsChecker } from 'vs/workbench/contrib/extensions/browser/deprecatedExtensionsChecker';
81-
import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile';
8281

8382
// Singletons
8483
registerSingleton(IExtensionsWorkbenchService, ExtensionsWorkbenchService, InstantiationType.Eager /* Auto updates extensions */);
@@ -473,7 +472,6 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi
473472
@IInstantiationService private readonly instantiationService: IInstantiationService,
474473
@IDialogService private readonly dialogService: IDialogService,
475474
@ICommandService private readonly commandService: ICommandService,
476-
@IUserDataProfileService private readonly userDataProfileService: IUserDataProfileService,
477475
) {
478476
super();
479477
const hasGalleryContext = CONTEXT_HAS_GALLERY.bindTo(contextKeyService);
@@ -517,31 +515,22 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi
517515

518516
// Global actions
519517
private registerGlobalActions(): void {
520-
const getTitle = (title: string) => !this.userDataProfileService.currentProfile.isDefault && this.userDataProfileService.currentProfile.useDefaultFlags?.extensions
521-
? `${title} (${localize('default profile', "Default Profile")})`
522-
: title;
523-
const registerOpenExtensionsActionDisposables = this._register(new DisposableStore());
524-
const registerOpenExtensionsAction = () => {
525-
registerOpenExtensionsActionDisposables.clear();
526-
registerOpenExtensionsActionDisposables.add(MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, {
527-
command: {
528-
id: VIEWLET_ID,
529-
title: getTitle(localize({ key: 'miPreferencesExtensions', comment: ['&& denotes a mnemonic'] }, "&&Extensions"))
530-
},
531-
group: '2_configuration',
532-
order: 3
533-
}));
534-
registerOpenExtensionsActionDisposables.add(MenuRegistry.appendMenuItem(MenuId.GlobalActivity, {
535-
command: {
536-
id: VIEWLET_ID,
537-
title: getTitle(localize('showExtensions', "Extensions"))
538-
},
539-
group: '2_configuration',
540-
order: 3
541-
}));
542-
};
543-
registerOpenExtensionsAction();
544-
this._register(Event.any(this.userDataProfileService.onDidChangeCurrentProfile, this.userDataProfileService.onDidUpdateCurrentProfile)(() => registerOpenExtensionsAction()));
518+
this._register(MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, {
519+
command: {
520+
id: VIEWLET_ID,
521+
title: localize({ key: 'miPreferencesExtensions', comment: ['&& denotes a mnemonic'] }, "&&Extensions")
522+
},
523+
group: '2_configuration',
524+
order: 3
525+
}));
526+
this._register(MenuRegistry.appendMenuItem(MenuId.GlobalActivity, {
527+
command: {
528+
id: VIEWLET_ID,
529+
title: localize('showExtensions', "Extensions")
530+
},
531+
group: '2_configuration',
532+
order: 3
533+
}));
545534

546535
this.registerExtensionAction({
547536
id: 'workbench.extensions.action.installExtensions',

0 commit comments

Comments
 (0)