Skip to content

Commit 97ab35d

Browse files
committed
implement feedback
1 parent db2de11 commit 97ab35d

File tree

11 files changed

+108
-49
lines changed

11 files changed

+108
-49
lines changed

src/vs/platform/environment/common/argv.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export interface NativeParsedArgs {
9292
editSessionId?: string;
9393
'locate-shell-integration-path'?: string;
9494
'profile'?: string;
95-
'transient'?: boolean;
95+
'profile-transient'?: boolean;
9696

9797
// chromium command line args: https://electronjs.org/docs/all#supported-chrome-command-line-switches
9898
'no-proxy-server'?: boolean;

src/vs/platform/environment/node/argv.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ export const OPTIONS: OptionDescriptions<Required<NativeParsedArgs>> = {
5050
'waitMarkerFilePath': { type: 'string' },
5151
'locale': { type: 'string', cat: 'o', args: 'locale', description: localize('locale', "The locale to use (e.g. en-US or zh-TW).") },
5252
'user-data-dir': { type: 'string', cat: 'o', args: 'dir', description: localize('userDataDir', "Specifies the directory that user data is kept in. Can be used to open multiple distinct instances of Code.") },
53-
'profile': { type: 'string', 'cat': 'o', args: 'settingsProfileName', description: localize('settingsProfileName', "Opens the provided folder or workspace with the given profile. If the profile does not exist, a new empty one is created. Use '--transient' argument to not to persist the profile.") },
53+
'profile': { type: 'string', 'cat': 'o', args: 'settingsProfileName', description: localize('settingsProfileName', "Opens the provided folder or workspace with the given profile. If the profile does not exist, a new empty one is created.") },
54+
'profile-transient': { type: 'boolean', 'cat': 'o', description: localize('transientProfile', "Creates an empty transient profile and opens the provided folder or workspace with this profile.") },
5455
'help': { type: 'boolean', cat: 'o', alias: 'h', description: localize('help', "Print usage.") },
5556

5657
'extensions-dir': { type: 'string', deprecates: ['extensionHomePath'], cat: 'e', args: 'dir', description: localize('extensionHomePath', "Set the root path for extensions.") },
@@ -130,7 +131,6 @@ export const OPTIONS: OptionDescriptions<Required<NativeParsedArgs>> = {
130131
'__enable-file-policy': { type: 'boolean' },
131132
'editSessionId': { type: 'string' },
132133
'locate-shell-integration-path': { type: 'string', args: ['bash', 'pwsh', 'zsh', 'fish'] },
133-
'transient': { type: 'boolean' },
134134

135135
// chromium flags
136136
'no-proxy-server': { type: 'boolean' },

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

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { IStringDictionary } from 'vs/base/common/collections';
2020
import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity';
2121
import { Promises } from 'vs/base/common/async';
2222
import { generateUuid } from 'vs/base/common/uuid';
23+
import { escapeRegExpCharacters } from 'vs/base/common/strings';
2324

2425
/**
2526
* Flags to indicate whether to use the default profile or not.
@@ -94,14 +95,16 @@ export interface IUserDataProfilesService {
9495

9596
readonly onDidResetWorkspaces: Event<void>;
9697

97-
createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: WorkspaceIdentifier, transient?: boolean): Promise<IUserDataProfile>;
98+
createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: WorkspaceIdentifier): Promise<IUserDataProfile>;
99+
createTransientProfile(workspaceIdentifier?: WorkspaceIdentifier): Promise<IUserDataProfile>;
98100
updateProfile(profile: IUserDataProfile, name: string, useDefaultFlags?: UseDefaultProfileFlags): Promise<IUserDataProfile>;
99-
removeProfile(profile: IUserDataProfile, donotRemoveIfAssociated?: boolean): Promise<void>;
101+
removeProfile(profile: IUserDataProfile): Promise<void>;
100102

101-
setProfileForWorkspace(workspaceIdentifier: WorkspaceIdentifier, profile: IUserDataProfile, transient?: boolean): Promise<void>;
103+
setProfileForWorkspace(workspaceIdentifier: WorkspaceIdentifier, profile: IUserDataProfile): Promise<void>;
102104
resetWorkspaces(): Promise<void>;
103105

104106
cleanUp(): Promise<void>;
107+
cleanUpTransientProfiles(): Promise<void>;
105108
}
106109

107110
export function reviveProfile(profile: UriDto<IUserDataProfile>, scheme: string): IUserDataProfile {
@@ -237,6 +240,19 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf
237240
return this._profilesObject;
238241
}
239242

243+
async createTransientProfile(workspaceIdentifier?: WorkspaceIdentifier): Promise<IUserDataProfile> {
244+
const namePrefix = `Temp`;
245+
const nameRegEx = new RegExp(`${escapeRegExpCharacters(namePrefix)}\\s(\\d+)`);
246+
let nameIndex = 0;
247+
for (const profile of this.profiles) {
248+
const matches = nameRegEx.exec(profile.name);
249+
const index = matches ? parseInt(matches[1]) : 0;
250+
nameIndex = index > nameIndex ? index : nameIndex;
251+
}
252+
const name = `${namePrefix} ${nameIndex + 1}`;
253+
return this.createProfile(name, undefined, workspaceIdentifier, true);
254+
}
255+
240256
async createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: WorkspaceIdentifier, transient?: boolean): Promise<IUserDataProfile> {
241257
if (!this.enabled) {
242258
throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`);
@@ -245,7 +261,7 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf
245261
const profile = await this.doCreateProfile(name, useDefaultFlags, transient);
246262

247263
if (workspaceIdentifier) {
248-
await this.setProfileForWorkspace(workspaceIdentifier, profile, transient);
264+
await this.setProfileForWorkspace(workspaceIdentifier, profile);
249265
}
250266

251267
return profile;
@@ -300,7 +316,7 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf
300316
return profile;
301317
}
302318

303-
async removeProfile(profileToRemove: IUserDataProfile, donotRemoveIfAssociated?: boolean): Promise<void> {
319+
async removeProfile(profileToRemove: IUserDataProfile): Promise<void> {
304320
if (!this.enabled) {
305321
throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`);
306322
}
@@ -312,10 +328,6 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf
312328
throw new Error(`Profile '${profileToRemove.name}' does not exist`);
313329
}
314330

315-
if (donotRemoveIfAssociated && this.isProfileAssociatedToWorkspace(profile)) {
316-
return;
317-
}
318-
319331
const joiners: Promise<void>[] = [];
320332
this._onWillRemoveProfile.fire({
321333
profile,
@@ -365,11 +377,11 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf
365377
return profile;
366378
}
367379

368-
async setProfileForWorkspace(workspaceIdentifier: WorkspaceIdentifier, profileToSet: IUserDataProfile, transient?: boolean): Promise<void> {
369-
this.setProfileForWorkspaceSync(workspaceIdentifier, profileToSet, transient);
380+
async setProfileForWorkspace(workspaceIdentifier: WorkspaceIdentifier, profileToSet: IUserDataProfile): Promise<void> {
381+
this.setProfileForWorkspaceSync(workspaceIdentifier, profileToSet);
370382
}
371383

372-
setProfileForWorkspaceSync(workspaceIdentifier: WorkspaceIdentifier, profileToSet: IUserDataProfile, transient?: boolean): void {
384+
setProfileForWorkspaceSync(workspaceIdentifier: WorkspaceIdentifier, profileToSet: IUserDataProfile): void {
373385
if (!this.enabled) {
374386
throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`);
375387
}
@@ -379,7 +391,7 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf
379391
throw new Error(`Profile '${profileToSet.name}' does not exist`);
380392
}
381393

382-
this.updateWorkspaceAssociation(workspaceIdentifier, profile, transient);
394+
this.updateWorkspaceAssociation(workspaceIdentifier, profile);
383395
}
384396

385397
unsetWorkspace(workspaceIdentifier: WorkspaceIdentifier, transient?: boolean): void {
@@ -409,6 +421,14 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf
409421
.map(child => this.fileService.del(child.resource, { recursive: true })));
410422
}
411423

424+
async cleanUpTransientProfiles(): Promise<void> {
425+
if (!this.enabled) {
426+
return;
427+
}
428+
const unAssociatedTransientProfiles = this.transientProfilesObject.profiles.filter(p => !this.isProfileAssociatedToWorkspace(p));
429+
await Promise.allSettled(unAssociatedTransientProfiles.map(p => this.removeProfile(p)));
430+
}
431+
412432
private getProfileForWorkspace(workspaceIdentifier: WorkspaceIdentifier): IUserDataProfile | undefined {
413433
const workspace = this.getWorkspace(workspaceIdentifier);
414434
return URI.isUri(workspace) ? this.transientProfilesObject.workspaces.get(workspace) ?? this.profilesObject.workspaces.get(workspace) : this.transientProfilesObject.emptyWindow ?? this.profilesObject.emptyWindow;

src/vs/platform/userDataProfile/electron-main/userDataProfile.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export const IUserDataProfilesMainService = refineServiceDecorator<IUserDataProf
2020
export interface IUserDataProfilesMainService extends IUserDataProfilesService {
2121
isEnabled(): boolean;
2222
getOrSetProfileForWorkspace(workspaceIdentifier: WorkspaceIdentifier, profileToSet?: IUserDataProfile): IUserDataProfile;
23-
setProfileForWorkspaceSync(workspaceIdentifier: WorkspaceIdentifier, profileToSet: IUserDataProfile, transient?: boolean): void;
23+
setProfileForWorkspaceSync(workspaceIdentifier: WorkspaceIdentifier, profileToSet: IUserDataProfile): void;
2424
checkAndCreateProfileFromCli(args: NativeParsedArgs): Promise<IUserDataProfile> | undefined;
2525
unsetWorkspace(workspaceIdentifier: WorkspaceIdentifier, transient?: boolean): void;
2626
readonly onWillCreateProfile: Event<WillCreateProfileEvent>;
@@ -47,17 +47,25 @@ export class UserDataProfilesMainService extends UserDataProfilesService impleme
4747
if (!this.isEnabled()) {
4848
return undefined;
4949
}
50-
if (!args.profile) {
51-
return undefined;
52-
}
5350
// Do not create the profile if folder/file arguments are not provided
5451
if (!args._.length && !args['folder-uri'] && !args['file-uri']) {
5552
return undefined;
5653
}
57-
if (this.profiles.some(p => p.name === args.profile)) {
58-
return undefined;
54+
if (args.profile) {
55+
if (this.profiles.some(p => p.name === args.profile)) {
56+
return undefined;
57+
}
58+
return this.createProfile(args.profile);
59+
}
60+
if (args['profile-transient']) {
61+
return this.createTransientProfile()
62+
.then(profile => {
63+
// Set the profile name to use
64+
args.profile = profile.name;
65+
return profile;
66+
});
5967
}
60-
return this.createProfile(args.profile, undefined, undefined, args.transient);
68+
return undefined;
6169
}
6270

6371
protected override saveStoredProfiles(storedProfiles: StoredUserDataProfile[]): void {

src/vs/platform/userDataProfile/electron-main/userDataTransientProfilesHandler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export class UserDataTransientProfilesHandler extends Disposable {
2828
const profile = this.userDataProfilesService.getOrSetProfileForWorkspace(workspace);
2929
if (profile.isTransient) {
3030
this.userDataProfilesService.unsetWorkspace(workspace, true);
31-
await this.userDataProfilesService.removeProfile(profile, true);
31+
await this.userDataProfilesService.cleanUpTransientProfiles();
3232
}
3333
}
3434

src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,22 @@ export class UserDataProfilesNativeService extends Disposable implements IUserDa
4848
this.onDidResetWorkspaces = this.channel.listen<void>('onDidResetWorkspaces');
4949
}
5050

51-
async createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: WorkspaceIdentifier, transient?: boolean): Promise<IUserDataProfile> {
52-
const result = await this.channel.call<UriDto<IUserDataProfile>>('createProfile', [name, useDefaultFlags, workspaceIdentifier, transient]);
51+
async createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: WorkspaceIdentifier): Promise<IUserDataProfile> {
52+
const result = await this.channel.call<UriDto<IUserDataProfile>>('createProfile', [name, useDefaultFlags, workspaceIdentifier]);
53+
return reviveProfile(result, this.profilesHome.scheme);
54+
}
55+
56+
async createTransientProfile(workspaceIdentifier?: WorkspaceIdentifier): Promise<IUserDataProfile> {
57+
const result = await this.channel.call<UriDto<IUserDataProfile>>('createTransientProfile', [workspaceIdentifier]);
5358
return reviveProfile(result, this.profilesHome.scheme);
5459
}
5560

5661
async setProfileForWorkspace(workspaceIdentifier: WorkspaceIdentifier, profile: IUserDataProfile): Promise<void> {
5762
await this.channel.call<UriDto<IUserDataProfile>>('setProfileForWorkspace', [workspaceIdentifier, profile]);
5863
}
5964

60-
removeProfile(profile: IUserDataProfile, donotRemoveIfAssociated?: boolean): Promise<void> {
61-
return this.channel.call('removeProfile', [profile, donotRemoveIfAssociated]);
65+
removeProfile(profile: IUserDataProfile): Promise<void> {
66+
return this.channel.call('removeProfile', [profile]);
6267
}
6368

6469
async updateProfile(profile: IUserDataProfile, name: string, useDefaultFlags?: UseDefaultProfileFlags): Promise<IUserDataProfile> {
@@ -74,5 +79,9 @@ export class UserDataProfilesNativeService extends Disposable implements IUserDa
7479
return this.channel.call('cleanUp');
7580
}
7681

82+
cleanUpTransientProfiles(): Promise<void> {
83+
return this.channel.call('cleanUpTransientProfiles');
84+
}
85+
7786
}
7887

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

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,31 +74,46 @@ suite('UserDataProfileService (Common)', () => {
7474
assert.deepStrictEqual(testObject.profiles[0].extensionsResource, undefined);
7575
});
7676

77-
test('create transient profile', async () => {
78-
const profile = await testObject.createProfile('transient', undefined, undefined, true);
77+
test('create transient profiles', async () => {
78+
const profile1 = await testObject.createTransientProfile();
79+
const profile2 = await testObject.createTransientProfile();
80+
const profile3 = await testObject.createTransientProfile();
81+
82+
assert.deepStrictEqual(testObject.profiles.length, 4);
83+
assert.deepStrictEqual(profile1.name, 'Temp 1');
84+
assert.deepStrictEqual(profile1.isTransient, true);
85+
assert.deepStrictEqual(testObject.profiles[1].id, profile1.id);
86+
assert.deepStrictEqual(profile2.name, 'Temp 2');
87+
assert.deepStrictEqual(profile2.isTransient, true);
88+
assert.deepStrictEqual(testObject.profiles[2].id, profile2.id);
89+
assert.deepStrictEqual(profile3.name, 'Temp 3');
90+
assert.deepStrictEqual(profile3.isTransient, true);
91+
assert.deepStrictEqual(testObject.profiles[3].id, profile3.id);
92+
});
7993

80-
assert.deepStrictEqual(profile.name, 'transient');
81-
assert.deepStrictEqual(profile.isTransient, true);
82-
assert.deepStrictEqual(testObject.profiles.length, 2);
83-
assert.deepStrictEqual(testObject.profiles[1].id, profile.id);
94+
test('create transient profile when a normal profile with Temp is already created', async () => {
95+
await testObject.createProfile('Temp 1');
96+
const profile1 = await testObject.createTransientProfile();
97+
98+
assert.deepStrictEqual(profile1.name, 'Temp 2');
99+
assert.deepStrictEqual(profile1.isTransient, true);
84100
});
85101

86102
test('profiles include default profile with extension resource defined when transiet prrofile is created', async () => {
87-
await testObject.createProfile('transient', undefined, undefined, true);
103+
await testObject.createTransientProfile();
88104

89105
assert.deepStrictEqual(testObject.profiles.length, 2);
90106
assert.deepStrictEqual(testObject.profiles[0].isDefault, true);
91107
assert.deepStrictEqual(testObject.profiles[0].extensionsResource?.toString(), joinPath(environmentService.userRoamingDataHome, 'extensions.json').toString());
92108
});
93109

94110
test('profiles include default profile with extension resource undefined when transiet prrofile is removed', async () => {
95-
const profile = await testObject.createProfile('transient', undefined, undefined, true);
111+
const profile = await testObject.createTransientProfile();
96112
await testObject.removeProfile(profile);
97113

98114
assert.deepStrictEqual(testObject.profiles.length, 1);
99115
assert.deepStrictEqual(testObject.profiles[0].isDefault, true);
100116
assert.deepStrictEqual(testObject.profiles[0].extensionsResource, undefined);
101117
});
102118

103-
104119
});

src/vs/platform/windows/electron-main/windowsMainService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1476,7 +1476,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
14761476
if (options.userDataProfileInfo) {
14771477
profile = this.userDataProfilesMainService.profiles.find(profile => profile.name === options.userDataProfileInfo!.name);
14781478
if (profile) {
1479-
this.userDataProfilesMainService.setProfileForWorkspaceSync(options.workspace ?? 'empty-window', profile, options.cli?.transient);
1479+
this.userDataProfilesMainService.setProfileForWorkspaceSync(options.workspace ?? 'empty-window', profile);
14801480
}
14811481
}
14821482

src/vs/workbench/contrib/userDataProfile/browser/userDataProfileActions.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class CreateFromCurrentProfileAction extends Action2 {
4141
});
4242
}
4343

44-
async run(accessor: ServicesAccessor, transient?: boolean) {
44+
async run(accessor: ServicesAccessor) {
4545
const quickInputService = accessor.get(IQuickInputService);
4646
const notificationService = accessor.get(INotificationService);
4747
const userDataProfileManagementService = accessor.get(IUserDataProfileManagementService);
@@ -58,7 +58,7 @@ class CreateFromCurrentProfileAction extends Action2 {
5858
});
5959
if (name) {
6060
try {
61-
await userDataProfileManagementService.createAndEnterProfile(name, undefined, true, transient);
61+
await userDataProfileManagementService.createAndEnterProfile(name, undefined, true);
6262
} catch (error) {
6363
notificationService.error(error);
6464
}
@@ -83,7 +83,7 @@ class CreateEmptyProfileAction extends Action2 {
8383
});
8484
}
8585

86-
async run(accessor: ServicesAccessor, transient?: boolean) {
86+
async run(accessor: ServicesAccessor) {
8787
const quickInputService = accessor.get(IQuickInputService);
8888
const userDataProfileManagementService = accessor.get(IUserDataProfileManagementService);
8989
const notificationService = accessor.get(INotificationService);
@@ -100,7 +100,7 @@ class CreateEmptyProfileAction extends Action2 {
100100
});
101101
if (name) {
102102
try {
103-
await userDataProfileManagementService.createAndEnterProfile(name, undefined, undefined, transient);
103+
await userDataProfileManagementService.createAndEnterProfile(name, undefined, undefined);
104104
} catch (error) {
105105
notificationService.error(error);
106106
}
@@ -153,8 +153,8 @@ registerAction2(class CreateTransientProfileAction extends Action2 {
153153
super({
154154
id: 'workbench.profiles.actions.createTransientProfile',
155155
title: {
156-
value: localize('create transient profile', "Create Transient Settings Profile..."),
157-
original: 'Create Transient Settings Profile...'
156+
value: localize('create transient profile', "Create Transient Settings Profile"),
157+
original: 'Create Transient Settings Profile'
158158
},
159159
category: PROFILES_CATEGORY,
160160
f1: true,
@@ -163,7 +163,7 @@ registerAction2(class CreateTransientProfileAction extends Action2 {
163163
}
164164

165165
async run(accessor: ServicesAccessor) {
166-
return accessor.get(ICommandService).executeCommand(CreateEmptyProfileAction.ID, true);
166+
return accessor.get(IUserDataProfileManagementService).createAndEnterTransientProfile();
167167
}
168168
});
169169

src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,22 @@ export class UserDataProfileManagementService extends Disposable implements IUse
4848

4949
private async onDidChangeCurrentProfile(e: DidChangeUserDataProfileEvent): Promise<void> {
5050
if (e.previous.isTransient) {
51-
await this.userDataProfilesService.removeProfile(e.previous, true);
51+
await this.userDataProfilesService.cleanUpTransientProfiles();
5252
}
5353
}
5454

55-
async createAndEnterProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, fromExisting?: boolean, transient?: boolean): Promise<IUserDataProfile> {
56-
const profile = await this.userDataProfilesService.createProfile(name, useDefaultFlags, this.getWorkspaceIdentifier(), transient);
55+
async createAndEnterProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, fromExisting?: boolean): Promise<IUserDataProfile> {
56+
const profile = await this.userDataProfilesService.createProfile(name, useDefaultFlags, this.getWorkspaceIdentifier());
5757
await this.enterProfile(profile, !!fromExisting);
5858
return profile;
5959
}
6060

61+
async createAndEnterTransientProfile(): Promise<IUserDataProfile> {
62+
const profile = await this.userDataProfilesService.createTransientProfile(this.getWorkspaceIdentifier());
63+
await this.enterProfile(profile, false);
64+
return profile;
65+
}
66+
6167
async renameProfile(profile: IUserDataProfile, name: string): Promise<void> {
6268
if (!this.userDataProfilesService.profiles.some(p => p.id === profile.id)) {
6369
throw new Error(`Settings profile ${profile.name} does not exist`);

0 commit comments

Comments
 (0)