From 2cdcaf24eebfa619ef9f6b246fe5a164689840ff Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 13 Jul 2016 12:51:46 +0200 Subject: [PATCH] create paths in cli process main fixes #7505 --- src/vs/code/electron-main/env.ts | 11 +++ src/vs/code/electron-main/main.ts | 14 +--- src/vs/code/node/cliProcessMain.ts | 70 ++++++++++--------- .../environment/common/environment.ts | 4 ++ .../environment/node/environmentService.ts | 16 ++++- 5 files changed, 67 insertions(+), 48 deletions(-) diff --git a/src/vs/code/electron-main/env.ts b/src/vs/code/electron-main/env.ts index f9dea6b67ac..0ec4f822394 100644 --- a/src/vs/code/electron-main/env.ts +++ b/src/vs/code/electron-main/env.ts @@ -10,9 +10,11 @@ import * as fs from 'original-fs'; import * as path from 'path'; import * as os from 'os'; import { app } from 'electron'; +import { mkdirp } from 'vs/base/node/pfs'; import * as arrays from 'vs/base/common/arrays'; import * as strings from 'vs/base/common/strings'; import * as paths from 'vs/base/common/paths'; +import { TPromise } from 'vs/base/common/winjs.base'; import * as platform from 'vs/base/common/platform'; import URI from 'vs/base/common/uri'; import * as types from 'vs/base/common/types'; @@ -66,6 +68,8 @@ export interface IEnvironmentService { appKeybindingsPath: string; mainIPCHandle: string; sharedIPCHandle: string; + + createPaths(): TPromise; } function getNumericValue(value: string, defaultValue: number, fallback: number = void 0) { @@ -226,6 +230,13 @@ export class EnvService implements IEnvironmentService { // use sha256 to ensure the userid value can be used in filenames and are unique return crypto.createHash('sha256').update(username).digest('hex').substr(0, 6); } + + createPaths(): TPromise { + const promises = [this.appSettingsHome, this.userHome, this.userExtensionsHome] + .map(p => mkdirp(p)); + + return TPromise.join(promises) as TPromise; + } } function parsePathArguments(cwd: string, args: string[], gotoLineMode?: boolean): string[] { diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index de56cbc336c..86b7c98fe1c 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -9,7 +9,6 @@ import * as nls from 'vs/nls'; import * as fs from 'original-fs'; import { app, ipcMain as ipc } from 'electron'; import { assign } from 'vs/base/common/objects'; -import { mkdirp } from 'vs/base/node/pfs'; import * as platform from 'vs/base/common/platform'; import { IProcessEnvironment, IEnvironmentService, EnvService } from 'vs/code/electron-main/env'; import { IWindowsService, WindowsManager } from 'vs/code/electron-main/windows'; @@ -255,17 +254,6 @@ function setupIPC(accessor: ServicesAccessor): TPromise { return setup(true); } -// TODO@Joao: what about in the cli process? -function createPaths(accessor: ServicesAccessor): TPromise { - const environmentService = accessor.get(IEnvironmentService); - - return TPromise.join([ - mkdirp(environmentService.appSettingsHome), - mkdirp(environmentService.userHome), - mkdirp(environmentService.userExtensionsHome) - ]) as any as TPromise; -} - // TODO: isolate const services = new ServiceCollection(); @@ -357,7 +345,7 @@ getUserEnvironment() // See also https://github.com/Microsoft/vscode/issues/4558 userEnv['VSCODE_NLS_CONFIG'] = process.env['VSCODE_NLS_CONFIG']; - return instantiationService.invokeFunction(createPaths) + return instantiationService.invokeFunction(a => a.get(IEnvironmentService).createPaths()) .then(() => instantiationService.invokeFunction(setupIPC)) .then(ipcServer => instantiationService.invokeFunction(main, ipcServer, userEnv)); }) diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index 4ea0eadc972..1399b2de7ec 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -134,44 +134,48 @@ export function main(argv: ParsedArgs): TPromise { const instantiationService: IInstantiationService = new InstantiationService(services); return instantiationService.invokeFunction(accessor => { - const services = new ServiceCollection(); - services.set(IEventService, new SyncDescriptor(EventService)); - services.set(IConfigurationService, new SyncDescriptor(NodeConfigurationService)); - services.set(IRequestService, new SyncDescriptor(NodeRequestService)); - services.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementService)); - services.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService)); + const envService = accessor.get(IEnvironmentService); - const { appRoot, extensionsPath, extensionDevelopmentPath, isBuilt } = accessor.get(IEnvironmentService); + return envService.createPaths().then(() => { + const { appRoot, extensionsPath, extensionDevelopmentPath, isBuilt } = envService; - if (isBuilt && !extensionDevelopmentPath && product.enableTelemetry) { - const appenders: AppInsightsAppender[] = []; + const services = new ServiceCollection(); + services.set(IEventService, new SyncDescriptor(EventService)); + services.set(IConfigurationService, new SyncDescriptor(NodeConfigurationService)); + services.set(IRequestService, new SyncDescriptor(NodeRequestService)); + services.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementService)); + services.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService)); - if (product.aiConfig && product.aiConfig.key) { - appenders.push(new AppInsightsAppender(eventPrefix, null, product.aiConfig.key)); + if (isBuilt && !extensionDevelopmentPath && product.enableTelemetry) { + const appenders: AppInsightsAppender[] = []; + + if (product.aiConfig && product.aiConfig.key) { + appenders.push(new AppInsightsAppender(eventPrefix, null, product.aiConfig.key)); + } + + if (product.aiConfig && product.aiConfig.asimovKey) { + appenders.push(new AppInsightsAppender(eventPrefix, null, product.aiConfig.asimovKey)); + } + + // It is important to dispose the AI adapter properly because + // only then they flush remaining data. + process.once('exit', () => appenders.forEach(a => a.dispose())); + + const config: ITelemetryServiceConfig = { + appender: combinedAppender(...appenders), + commonProperties: resolveCommonProperties(product.commit, pkg.version), + piiPaths: [appRoot, extensionsPath] + }; + + services.set(ITelemetryService, new SyncDescriptor(TelemetryService, config)); + } else { + services.set(ITelemetryService, NullTelemetryService); } - if (product.aiConfig && product.aiConfig.asimovKey) { - appenders.push(new AppInsightsAppender(eventPrefix, null, product.aiConfig.asimovKey)); - } + const instantiationService2 = instantiationService.createChild(services); + const main = instantiationService2.createInstance(Main); - // It is important to dispose the AI adapter properly because - // only then they flush remaining data. - process.once('exit', () => appenders.forEach(a => a.dispose())); - - const config: ITelemetryServiceConfig = { - appender: combinedAppender(...appenders), - commonProperties: resolveCommonProperties(product.commit, pkg.version), - piiPaths: [appRoot, extensionsPath] - }; - - services.set(ITelemetryService, new SyncDescriptor(TelemetryService, config)); - } else { - services.set(ITelemetryService, NullTelemetryService); - } - - const instantiationService2 = instantiationService.createChild(services); - const main = instantiationService2.createInstance(Main); - - return main.run(argv); + return main.run(argv); + }); }); } diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index 8855776d914..b0f02a8a3f7 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { TPromise } from 'vs/base/common/winjs.base'; export const IEnvironmentService = createDecorator('environmentService'); @@ -11,8 +12,11 @@ export interface IEnvironmentService { _serviceBrand: any; appRoot: string; + userHome: string; userDataPath: string; extensionsPath: string; extensionDevelopmentPath: string; isBuilt: boolean; + + createPaths(): TPromise; } diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index f0c7100c607..d61457ec57f 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -9,8 +9,10 @@ import product from 'vs/platform/product'; import pkg from 'vs/platform/package'; import * as os from 'os'; import * as path from 'path'; +import { mkdirp } from 'vs/base/node/pfs'; import { parseArgs } from 'vs/code/node/argv'; import URI from 'vs/base/common/uri'; +import { TPromise } from 'vs/base/common/winjs.base'; export class EnvironmentService implements IEnvironmentService { @@ -19,6 +21,9 @@ export class EnvironmentService implements IEnvironmentService { private _appRoot: string; get appRoot(): string { return this._appRoot; } + private _userHome: string; + get userHome(): string { return this._userHome; } + private _userDataPath: string; get userDataPath(): string { return this._userDataPath; } @@ -36,10 +41,17 @@ export class EnvironmentService implements IEnvironmentService { this._appRoot = path.dirname(URI.parse(require.toUrl('')).fsPath); this._userDataPath = paths.getUserDataPath(process.platform, pkg.name, process.argv); - const userHome = path.join(os.homedir(), product.dataFolderName); - this._extensionsPath = argv.extensionHomePath || path.join(userHome, 'extensions'); + this._userHome = path.join(os.homedir(), product.dataFolderName); + this._extensionsPath = argv.extensionHomePath || path.join(this._userHome, 'extensions'); this._extensionsPath = path.normalize(this._extensionsPath); this._extensionDevelopmentPath = argv.extensionDevelopmentPath; } + + createPaths(): TPromise { + const promises = [this.userHome, this.extensionsPath] + .map(p => mkdirp(p)); + + return TPromise.join(promises) as TPromise; + } } \ No newline at end of file