Skip to content

Commit be5af93

Browse files
sandy081bpasero
andauthored
create the profile on main side (microsoft#158525)
* create the profile on main side * 💄 Co-authored-by: Benjamin Pasero <[email protected]>
1 parent 28f604d commit be5af93

File tree

11 files changed

+80
-75
lines changed

11 files changed

+80
-75
lines changed

src/vs/code/electron-main/app.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ export class CodeApplication extends Disposable {
128128
@IConfigurationService private readonly configurationService: IConfigurationService,
129129
@IStateMainService private readonly stateMainService: IStateMainService,
130130
@IFileService private readonly fileService: IFileService,
131-
@IProductService private readonly productService: IProductService
131+
@IProductService private readonly productService: IProductService,
132+
@IUserDataProfilesMainService private readonly userDataProfilesMainService: IUserDataProfilesMainService,
132133
) {
133134
super();
134135

@@ -534,6 +535,12 @@ export class CodeApplication extends Disposable {
534535
// Setup Handlers
535536
this.setUpHandlers(appInstantiationService);
536537

538+
// Ensure profile exists when passed in from CLI
539+
const profilePromise = this.userDataProfilesMainService.checkAndCreateProfileFromCli(this.environmentMainService.args);
540+
if (profilePromise) {
541+
await profilePromise;
542+
}
543+
537544
// Init Channels
538545
appInstantiationService.invokeFunction(accessor => this.initChannels(accessor, mainProcessElectronServer, sharedProcessClient));
539546

src/vs/platform/launch/electron-main/launchMainService.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { IWindowSettings } from 'vs/platform/window/common/window';
2121
import { IOpenConfiguration, IWindowsMainService, OpenContext } from 'vs/platform/windows/electron-main/windows';
2222
import { isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace';
2323
import { IWorkspacesManagementMainService } from 'vs/platform/workspaces/electron-main/workspacesManagementMainService';
24+
import { IUserDataProfilesMainService } from 'vs/platform/userDataProfile/electron-main/userDataProfile';
2425

2526
export const ID = 'launchMainService';
2627
export const ILaunchMainService = createDecorator<ILaunchMainService>(ID);
@@ -46,7 +47,8 @@ export class LaunchMainService implements ILaunchMainService {
4647
@IWindowsMainService private readonly windowsMainService: IWindowsMainService,
4748
@IURLService private readonly urlService: IURLService,
4849
@IWorkspacesManagementMainService private readonly workspacesManagementMainService: IWorkspacesManagementMainService,
49-
@IConfigurationService private readonly configurationService: IConfigurationService
50+
@IConfigurationService private readonly configurationService: IConfigurationService,
51+
@IUserDataProfilesMainService private readonly userDataProfilesMainService: IUserDataProfilesMainService,
5052
) { }
5153

5254
async start(args: NativeParsedArgs, userEnv: IProcessEnvironment): Promise<void> {
@@ -114,6 +116,12 @@ export class LaunchMainService implements ILaunchMainService {
114116
const waitMarkerFileURI = args.wait && args.waitMarkerFilePath ? URI.file(args.waitMarkerFilePath) : undefined;
115117
const remoteAuthority = args.remote || undefined;
116118

119+
// Ensure profile exists when passed in from CLI
120+
const profilePromise = this.userDataProfilesMainService.checkAndCreateProfileFromCli(args);
121+
if (profilePromise) {
122+
await profilePromise;
123+
}
124+
117125
const baseConfig: IOpenConfiguration = {
118126
context,
119127
cli: args,

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,6 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf
226226
return this._profilesObject;
227227
}
228228

229-
async reload(): Promise<IUserDataProfile[]> {
230-
this._profilesObject = undefined;
231-
return this.profiles;
232-
}
233-
234229
getProfile(workspaceIdentifier: WorkspaceIdentifier, profileToUseIfNotSet: IUserDataProfile): IUserDataProfile {
235230
if (!this.enabled) {
236231
return this.defaultProfile;
@@ -323,6 +318,10 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf
323318
}
324319

325320
async setProfileForWorkspace(profileToSet: IUserDataProfile, workspaceIdentifier: WorkspaceIdentifier): Promise<void> {
321+
this.setProfileForWorkspaceSync(profileToSet, workspaceIdentifier);
322+
}
323+
324+
setProfileForWorkspaceSync(profileToSet: IUserDataProfile, workspaceIdentifier: WorkspaceIdentifier): void {
326325
if (!this.enabled) {
327326
throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`);
328327
}

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

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'
1414
import { IUserDataProfilesService, WorkspaceIdentifier, StoredUserDataProfile, StoredProfileAssociations, WillCreateProfileEvent, WillRemoveProfileEvent, IUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile';
1515
import { UserDataProfilesService } from 'vs/platform/userDataProfile/node/userDataProfile';
1616
import { IStringDictionary } from 'vs/base/common/collections';
17+
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
1718

1819
export const IUserDataProfilesMainService = refineServiceDecorator<IUserDataProfilesService, IUserDataProfilesMainService>(IUserDataProfilesService);
1920
export interface IUserDataProfilesMainService extends IUserDataProfilesService {
2021
isEnabled(): boolean;
2122
unsetWorkspace(workspaceIdentifier: WorkspaceIdentifier): Promise<void>;
22-
reload(): Promise<IUserDataProfile[]>;
23+
setProfileForWorkspaceSync(profileToSet: IUserDataProfile, workspaceIdentifier: WorkspaceIdentifier): void;
24+
checkAndCreateProfileFromCli(args: NativeParsedArgs): Promise<IUserDataProfile> | undefined;
2325
readonly onWillCreateProfile: Event<WillCreateProfileEvent>;
2426
readonly onWillRemoveProfile: Event<WillRemoveProfileEvent>;
2527
}
@@ -40,6 +42,23 @@ export class UserDataProfilesMainService extends UserDataProfilesService impleme
4042
return this.enabled;
4143
}
4244

45+
checkAndCreateProfileFromCli(args: NativeParsedArgs): Promise<IUserDataProfile> | undefined {
46+
if (!this.isEnabled()) {
47+
return undefined;
48+
}
49+
if (!args.profile) {
50+
return undefined;
51+
}
52+
// Do not create the profile if folder/file arguments are not provided
53+
if (!args._.length && !args['folder-uri'] && !args['file-uri']) {
54+
return undefined;
55+
}
56+
if (this.profiles.some(p => p.name === args.profile)) {
57+
return undefined;
58+
}
59+
return this.createProfile(args.profile);
60+
}
61+
4362
protected override saveStoredProfiles(storedProfiles: StoredUserDataProfile[]): void {
4463
this.stateMainService.setItem(UserDataProfilesMainService.PROFILES_KEY, storedProfiles);
4564
}

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,6 @@ export class UserDataProfilesNativeService extends Disposable implements IUserDa
7171
return this.channel.call('resetWorkspaces');
7272
}
7373

74-
async reload(): Promise<void> {
75-
const all = await this.channel.call<UriDto<IUserDataProfile>[]>('reload');
76-
this._profiles = all.map(profile => reviveProfile(profile, this.profilesHome.scheme));
77-
}
78-
7974
getProfile(workspaceIdentifier: WorkspaceIdentifier, profileToUseIfNotSet: IUserDataProfile): IUserDataProfile { throw new Error('Not implemented'); }
8075
}
8176

src/vs/platform/window/common/window.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -273,18 +273,6 @@ export interface IOSConfiguration {
273273
readonly hostname: string;
274274
}
275275

276-
export interface IUserDataProfileInfo {
277-
readonly name?: string;
278-
}
279-
280-
export function isUserDataProfileInfo(thing: unknown): thing is IUserDataProfileInfo {
281-
const candidate = thing as IUserDataProfileInfo | undefined;
282-
283-
return !!(candidate && typeof candidate === 'object'
284-
&& typeof candidate.name === 'string'
285-
);
286-
}
287-
288276
export interface INativeWindowConfiguration extends IWindowConfiguration, NativeParsedArgs, ISandboxConfiguration {
289277
mainPid: number;
290278

@@ -295,7 +283,7 @@ export interface INativeWindowConfiguration extends IWindowConfiguration, Native
295283

296284
profiles: {
297285
all: readonly UriDto<IUserDataProfile>[];
298-
workspace: UriDto<IUserDataProfile> | IUserDataProfileInfo;
286+
profile: UriDto<IUserDataProfile>;
299287
};
300288

301289
homeDir: string;

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ import { IWindowState, ICodeWindow, ILoadEvent, WindowMode, WindowError, LoadRea
4141
import { Color } from 'vs/base/common/color';
4242
import { IPolicyService } from 'vs/platform/policy/common/policy';
4343
import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
44-
import { revive } from 'vs/base/common/marshalling';
4544
import { IStateMainService } from 'vs/platform/state/electron-main/state';
4645
import product from 'vs/platform/product/common/product';
4746

@@ -121,7 +120,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
121120

122121
get openedWorkspace(): IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | undefined { return this._config?.workspace; }
123122

124-
get profile(): IUserDataProfile | undefined { return this.config ? this.userDataProfilesService.getProfile(this.config.workspace ?? 'empty-window', revive(this.config.profiles.workspace)) : undefined; }
123+
get profile(): IUserDataProfile | undefined { return this.config ? this.userDataProfilesService.getProfile(this.config.workspace ?? 'empty-window', this.userDataProfilesService.profiles.find(profile => profile.id === this.config?.profiles.profile.id) ?? this.userDataProfilesService.defaultProfile) : undefined; }
125124

126125
get remoteAuthority(): string | undefined { return this._config?.remoteAuthority; }
127126

@@ -972,7 +971,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
972971
configuration.policiesData = this.policyService.serialize(); // set policies data again
973972
configuration.profiles = {
974973
all: this.userDataProfilesService.profiles,
975-
workspace: this.profile || this.userDataProfilesService.defaultProfile
974+
profile: this.profile || this.userDataProfilesService.defaultProfile
976975
};
977976

978977
// Load config

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

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import { IProductService } from 'vs/platform/product/common/productService';
3838
import { IProtocolMainService } from 'vs/platform/protocol/electron-main/protocol';
3939
import { getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts';
4040
import { IStateMainService } from 'vs/platform/state/electron-main/state';
41-
import { IAddFoldersRequest, INativeOpenFileRequest, INativeWindowConfiguration, IOpenEmptyWindowOptions, IPath, IPathsToWaitFor, isFileToOpen, isFolderToOpen, isWorkspaceToOpen, IWindowOpenable, IWindowSettings, IUserDataProfileInfo } from 'vs/platform/window/common/window';
41+
import { IAddFoldersRequest, INativeOpenFileRequest, INativeWindowConfiguration, IOpenEmptyWindowOptions, IPath, IPathsToWaitFor, isFileToOpen, isFolderToOpen, isWorkspaceToOpen, IWindowOpenable, IWindowSettings } from 'vs/platform/window/common/window';
4242
import { CodeWindow } from 'vs/platform/windows/electron-main/windowImpl';
4343
import { IOpenConfiguration, IOpenEmptyConfiguration, IWindowsCountChangedEvent, IWindowsMainService, OpenContext } from 'vs/platform/windows/electron-main/windows';
4444
import { findWindowOnExtensionDevelopmentPath, findWindowOnFile, findWindowOnWorkspaceOrFolder } from 'vs/platform/windows/electron-main/windowsFinder';
@@ -51,8 +51,9 @@ import { IWorkspacesManagementMainService } from 'vs/platform/workspaces/electro
5151
import { ICodeWindow, UnloadReason } from 'vs/platform/window/electron-main/window';
5252
import { IThemeMainService } from 'vs/platform/theme/electron-main/themeMainService';
5353
import { IEditorOptions, ITextEditorOptions } from 'vs/platform/editor/common/editor';
54-
import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
54+
import { IUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile';
5555
import { IPolicyService } from 'vs/platform/policy/common/policy';
56+
import { IUserDataProfilesMainService } from 'vs/platform/userDataProfile/electron-main/userDataProfile';
5657

5758
//#region Helper Interfaces
5859

@@ -79,6 +80,10 @@ interface IOpenBrowserWindowOptions {
7980
readonly userDataProfileInfo?: IUserDataProfileInfo;
8081
}
8182

83+
interface IUserDataProfileInfo {
84+
readonly name?: string;
85+
}
86+
8287
interface IPathResolveOptions {
8388

8489
/**
@@ -208,7 +213,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
208213
@IStateMainService private readonly stateMainService: IStateMainService,
209214
@IPolicyService private readonly policyService: IPolicyService,
210215
@IEnvironmentMainService private readonly environmentMainService: IEnvironmentMainService,
211-
@IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService,
216+
@IUserDataProfilesMainService private readonly userDataProfilesMainService: IUserDataProfilesMainService,
212217
@ILifecycleMainService private readonly lifecycleMainService: ILifecycleMainService,
213218
@IBackupMainService private readonly backupMainService: IBackupMainService,
214219
@IConfigurationService private readonly configurationService: IConfigurationService,
@@ -1342,8 +1347,8 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
13421347
backupPath: options.emptyWindowBackupInfo ? join(this.environmentMainService.backupHome, options.emptyWindowBackupInfo.backupFolder) : undefined,
13431348

13441349
profiles: {
1345-
all: this.userDataProfilesService.profiles,
1346-
workspace: options.userDataProfileInfo ?? this.userDataProfilesService.getProfile(options.workspace ?? 'empty-window', (options.windowToUse ?? this.getLastActiveWindow())?.profile ?? this.userDataProfilesService.defaultProfile),
1350+
all: this.userDataProfilesMainService.profiles,
1351+
profile: this.resolveProfileForBrowserWindow(options)
13471352
},
13481353

13491354
homeDir: this.environmentMainService.userHome.fsPath,
@@ -1465,6 +1470,25 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
14651470
return window;
14661471
}
14671472

1473+
private resolveProfileForBrowserWindow(options: IOpenBrowserWindowOptions) {
1474+
1475+
// Resolve profile by name if provided
1476+
let profile: IUserDataProfile | undefined;
1477+
if (options.userDataProfileInfo) {
1478+
profile = this.userDataProfilesMainService.profiles.find(profile => profile.name === options.userDataProfileInfo!.name);
1479+
if (profile) {
1480+
this.userDataProfilesMainService.setProfileForWorkspaceSync(profile, options.workspace ?? 'empty-window');
1481+
}
1482+
}
1483+
1484+
// Otherwise use associated profile
1485+
if (!profile) {
1486+
profile = this.userDataProfilesMainService.getProfile(options.workspace ?? 'empty-window', (options.windowToUse ?? this.getLastActiveWindow())?.profile ?? this.userDataProfilesMainService.defaultProfile);
1487+
}
1488+
1489+
return profile;
1490+
}
1491+
14681492
private doOpenInBrowserWindow(window: ICodeWindow, configuration: INativeWindowConfiguration, options: IOpenBrowserWindowOptions): void {
14691493

14701494
// Register window for backups

src/vs/workbench/electron-sandbox/desktop.main.ts

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import { localize } from 'vs/nls';
77
import product from 'vs/platform/product/common/product';
8-
import { INativeWindowConfiguration, IUserDataProfileInfo, isUserDataProfileInfo, zoomLevelToZoomFactor } from 'vs/platform/window/common/window';
8+
import { INativeWindowConfiguration, zoomLevelToZoomFactor } from 'vs/platform/window/common/window';
99
import { Workbench } from 'vs/workbench/browser/workbench';
1010
import { NativeWindow } from 'vs/workbench/electron-sandbox/window';
1111
import { setZoomLevel, setZoomFactor, setFullscreen } from 'vs/base/browser/browser';
@@ -50,7 +50,7 @@ import { isCI, isMacintosh } from 'vs/base/common/platform';
5050
import { Schemas } from 'vs/base/common/network';
5151
import { DiskFileSystemProvider } from 'vs/workbench/services/files/electron-sandbox/diskFileSystemProvider';
5252
import { FileUserDataProvider } from 'vs/platform/userData/common/fileUserDataProvider';
53-
import { IUserDataProfile, IUserDataProfilesService, reviveProfile } from 'vs/platform/userDataProfile/common/userDataProfile';
53+
import { IUserDataProfilesService, reviveProfile } from 'vs/platform/userDataProfile/common/userDataProfile';
5454
import { UserDataProfilesNativeService } from 'vs/platform/userDataProfile/electron-sandbox/userDataProfile';
5555
import { PolicyChannelClient } from 'vs/platform/policy/common/policyIpc';
5656
import { IPolicyService, NullPolicyService } from 'vs/platform/policy/common/policy';
@@ -241,24 +241,8 @@ export class DesktopMain extends Disposable {
241241
// User Data Profiles
242242
const userDataProfilesService = new UserDataProfilesNativeService(this.configuration.profiles.all, mainProcessService, environmentService);
243243
serviceCollection.set(IUserDataProfilesService, userDataProfilesService);
244-
245-
// User Data profile
246-
let profile: IUserDataProfile | undefined, profileInfo: IUserDataProfileInfo | undefined;
247-
if (isUserDataProfileInfo(this.configuration.profiles.workspace)) {
248-
profileInfo = this.configuration.profiles.workspace;
249-
} else {
250-
profile = reviveProfile(this.configuration.profiles.workspace, userDataProfilesService.profilesHome.scheme);
251-
}
252-
const userDataProfileService = new UserDataProfileService(profile ?? userDataProfilesService.defaultProfile, userDataProfilesService);
244+
const userDataProfileService = new UserDataProfileService(reviveProfile(this.configuration.profiles.profile, userDataProfilesService.profilesHome.scheme), userDataProfilesService);
253245
serviceCollection.set(IUserDataProfileService, userDataProfileService);
254-
const payload = this.resolveWorkspaceInitializationPayload(environmentService);
255-
if (profileInfo?.name) {
256-
await userDataProfileService.initProfileWithName(profileInfo.name, payload);
257-
258-
if (!userDataProfilesService.profiles.some(profile => profile.id === userDataProfileService.currentProfile.id)) {
259-
await userDataProfilesService.reload(); // reload profiles if the current profile does not exist
260-
}
261-
}
262246

263247
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
264248
//
@@ -270,6 +254,7 @@ export class DesktopMain extends Disposable {
270254
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
271255

272256
// Create services that require resolving in parallel
257+
const payload = this.resolveWorkspaceInitializationPayload(environmentService);
273258
const [configurationService, storageService] = await Promise.all([
274259
this.createWorkspaceService(payload, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, uriIdentityService, logService, policyService).then(service => {
275260

src/vs/workbench/services/userDataProfile/common/userDataProfileService.ts

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
import { Promises } from 'vs/base/common/async';
77
import { Emitter } from 'vs/base/common/event';
88
import { Disposable } from 'vs/base/common/lifecycle';
9-
import { IUserDataProfile, IUserDataProfilesService, WorkspaceIdentifier } from 'vs/platform/userDataProfile/common/userDataProfile';
10-
import { IAnyWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace';
9+
import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
1110
import { DidChangeUserDataProfileEvent, IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile';
1211

1312
export class UserDataProfileService extends Disposable implements IUserDataProfileService {
@@ -25,7 +24,7 @@ export class UserDataProfileService extends Disposable implements IUserDataProfi
2524

2625
constructor(
2726
currentProfile: IUserDataProfile,
28-
@IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService
27+
@IUserDataProfilesService userDataProfilesService: IUserDataProfilesService
2928
) {
3029
super();
3130
this._currentProfile = currentProfile;
@@ -65,22 +64,4 @@ export class UserDataProfileService extends Disposable implements IUserDataProfi
6564
await Promises.settled(joiners);
6665
}
6766

68-
async initProfileWithName(profileName: string, anyWorkspaceIdentifier: IAnyWorkspaceIdentifier): Promise<void> {
69-
if (this.currentProfile.name === profileName) {
70-
return;
71-
}
72-
const workspaceIdentifier = this.getWorkspaceIdentifier(anyWorkspaceIdentifier);
73-
let profile = this.userDataProfilesService.profiles.find(p => p.name === profileName);
74-
if (profile) {
75-
await this.userDataProfilesService.setProfileForWorkspace(profile, workspaceIdentifier);
76-
} else {
77-
profile = await this.userDataProfilesService.createProfile(profileName, undefined, workspaceIdentifier);
78-
}
79-
await this.updateCurrentProfile(profile, false);
80-
}
81-
82-
private getWorkspaceIdentifier(anyWorkspaceIdentifier: IAnyWorkspaceIdentifier): WorkspaceIdentifier {
83-
return isSingleFolderWorkspaceIdentifier(anyWorkspaceIdentifier) || isWorkspaceIdentifier(anyWorkspaceIdentifier) ? anyWorkspaceIdentifier : 'empty-window';
84-
}
85-
8667
}

0 commit comments

Comments
 (0)