From 855bcc50ffa3ae8d6f2e28fc4757d367ca30a665 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 6 Oct 2016 14:19:51 +0200 Subject: [PATCH] get rid of IEnvService (fixes #10656) --- src/vs/code/electron-main/main.ts | 22 +++--- src/vs/code/electron-main/menus.ts | 6 +- .../code/electron-main/{env.ts => paths.ts} | 73 +++++-------------- src/vs/code/electron-main/windows.ts | 15 ++-- .../environment/node/environmentService.ts | 7 +- 5 files changed, 45 insertions(+), 78 deletions(-) rename src/vs/code/electron-main/{env.ts => paths.ts} (61%) diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index fc66bef8e8c..8a1798c023d 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -11,7 +11,7 @@ import { assign } from 'vs/base/common/objects'; import * as platform from 'vs/base/common/platform'; import { parseMainProcessArgv, ParsedArgs } from 'vs/platform/environment/node/argv'; import { mkdirp } from 'vs/base/node/pfs'; -import { IEnvService, EnvService } from 'vs/code/electron-main/env'; +import { validatePaths } from 'vs/code/electron-main/paths'; import { IWindowsService, WindowsManager, WindowEventService } from 'vs/code/electron-main/windows'; import { IWindowEventService } from 'vs/code/common/windows'; import { WindowEventChannel } from 'vs/code/common/windowsIpc'; @@ -72,7 +72,6 @@ function quit(accessor: ServicesAccessor, arg?: any) { function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platform.IProcessEnvironment): void { const instantiationService = accessor.get(IInstantiationService); const logService = accessor.get(ILogService); - const envService = accessor.get(IEnvService); const environmentService = accessor.get(IEnvironmentService); const windowsService = accessor.get(IWindowsService); const windowEventService = accessor.get(IWindowEventService); @@ -103,7 +102,7 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo logService.log('Starting VS Code in verbose mode'); logService.log(`from: ${environmentService.appRoot}`); - logService.log('args:', envService.cliArgs); + logService.log('args:', environmentService.args); // Setup Windows mutex let windowsMutex: Mutex = null; @@ -253,19 +252,18 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo updateService.initialize(); // Open our first window - if (envService.cliArgs['new-window'] && envService.cliArgs._.length === 0) { - windowsService.open({ cli: envService.cliArgs, forceNewWindow: true, forceEmpty: true }); // new window if "-n" was used without paths - } else if (global.macOpenFiles && global.macOpenFiles.length && (!envService.cliArgs._ || !envService.cliArgs._.length)) { - windowsService.open({ cli: envService.cliArgs, pathsToOpen: global.macOpenFiles }); // mac: open-file event received on startup + if (environmentService.args['new-window'] && environmentService.args._.length === 0) { + windowsService.open({ cli: environmentService.args, forceNewWindow: true, forceEmpty: true }); // new window if "-n" was used without paths + } else if (global.macOpenFiles && global.macOpenFiles.length && (!environmentService.args._ || !environmentService.args._.length)) { + windowsService.open({ cli: environmentService.args, pathsToOpen: global.macOpenFiles }); // mac: open-file event received on startup } else { - windowsService.open({ cli: envService.cliArgs, forceNewWindow: envService.cliArgs['new-window'], diffMode: envService.cliArgs.diff }); // default: read paths from cli + windowsService.open({ cli: environmentService.args, forceNewWindow: environmentService.args['new-window'], diffMode: environmentService.args.diff }); // default: read paths from cli } } function setupIPC(accessor: ServicesAccessor): TPromise { const logService = accessor.get(ILogService); const environmentService = accessor.get(IEnvironmentService); - const envService = accessor.get(IEnvService); function setup(retry: boolean): TPromise { return serve(environmentService.mainIPCHandle).then(server => { @@ -301,7 +299,7 @@ function setupIPC(accessor: ServicesAccessor): TPromise { const channel = client.getChannel('launch'); const service = new LaunchChannelClient(channel); - return service.start(envService.cliArgs, process.env) + return service.start(environmentService.args, process.env) .then(() => client.dispose()) .then(() => TPromise.wrapError('Sent env to running instance. Terminating...')); }, @@ -426,7 +424,7 @@ function getEnvironment(accessor: ServicesAccessor): TPromise { const paths = [environmentService.appSettingsHome, environmentService.userHome, environmentService.extensionsPath]; - + return TPromise.join(paths.map(p => mkdirp(p))) as TPromise; } @@ -435,6 +433,7 @@ function start(): void { try { args = parseMainProcessArgv(process.argv); + args = validatePaths(args); } catch (err) { console.error(err.message); process.exit(1); @@ -445,7 +444,6 @@ function start(): void { const services = new ServiceCollection(); services.set(IEnvironmentService, new SyncDescriptor(EnvironmentService, args, process.execPath)); - services.set(IEnvService, new SyncDescriptor(EnvService)); services.set(ILogService, new SyncDescriptor(MainLogService)); services.set(IWindowsService, new SyncDescriptor(WindowsManager)); services.set(IWindowEventService, new SyncDescriptor(WindowEventService)); diff --git a/src/vs/code/electron-main/menus.ts b/src/vs/code/electron-main/menus.ts index 1a05bee2bb0..3e4f3944257 100644 --- a/src/vs/code/electron-main/menus.ts +++ b/src/vs/code/electron-main/menus.ts @@ -8,7 +8,7 @@ import * as nls from 'vs/nls'; import * as platform from 'vs/base/common/platform'; import * as arrays from 'vs/base/common/arrays'; -import { IEnvService } from 'vs/code/electron-main/env'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ipcMain as ipc, app, shell, dialog, Menu, MenuItem } from 'electron'; import { IWindowsService } from 'vs/code/electron-main/windows'; import { IPath, VSCodeWindow } from 'vs/code/electron-main/window'; @@ -45,7 +45,7 @@ export class VSCodeMenu { @IUpdateService private updateService: IUpdateService, @IConfigurationService private configurationService: IConfigurationService, @IWindowsService private windowsService: IWindowsService, - @IEnvService private envService: IEnvService + @IEnvironmentService private environmentService: IEnvironmentService ) { this.actionIdKeybindingRequests = []; @@ -405,7 +405,7 @@ export class VSCodeMenu { return new MenuItem({ label: unMnemonicLabel(path), click: (menuItem, win, event) => { const openInNewWindow = event && ((!platform.isMacintosh && event.ctrlKey) || (platform.isMacintosh && event.metaKey)); - const success = !!this.windowsService.open({ cli: this.envService.cliArgs, pathsToOpen: [path], forceNewWindow: openInNewWindow }); + const success = !!this.windowsService.open({ cli: this.environmentService.args, pathsToOpen: [path], forceNewWindow: openInNewWindow }); if (!success) { this.windowsService.removeFromRecentPathsList(path); this.updateMenu(); diff --git a/src/vs/code/electron-main/env.ts b/src/vs/code/electron-main/paths.ts similarity index 61% rename from src/vs/code/electron-main/env.ts rename to src/vs/code/electron-main/paths.ts index 299ba7ce47c..4e361d80ba1 100644 --- a/src/vs/code/electron-main/env.ts +++ b/src/vs/code/electron-main/paths.ts @@ -12,55 +12,26 @@ import * as strings from 'vs/base/common/strings'; import * as paths from 'vs/base/common/paths'; import * as platform from 'vs/base/common/platform'; import * as types from 'vs/base/common/types'; -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { parseMainProcessArgv, ParsedArgs } from 'vs/platform/environment/node/argv'; +import { ParsedArgs } from 'vs/platform/environment/node/argv'; -export const IEnvService = createDecorator('mainEnvironmentService'); +export function validatePaths(args: ParsedArgs): ParsedArgs { -export interface IEnvService { - _serviceBrand: any; - cliArgs: ParsedArgs; -} + // Realpath/normalize paths and watch out for goto line mode + const paths = doValidatePaths(args._, args.goto); -export class EnvService implements IEnvService { - - _serviceBrand: any; - - private _cliArgs: ParsedArgs; - get cliArgs(): ParsedArgs { return this._cliArgs; } - - constructor() { - const argv = parseMainProcessArgv(process.argv); - const paths = parsePathArguments(argv._, argv.goto); - - this._cliArgs = Object.freeze({ - _: paths, - performance: argv.performance, - verbose: argv.verbose, - debugPluginHost: argv.debugPluginHost, - debugBrkPluginHost: argv.debugBrkPluginHost, - logExtensionHostCommunication: argv.logExtensionHostCommunication, - 'new-window': argv['new-window'], - 'reuse-window': argv['reuse-window'], - goto: argv.goto, - diff: argv.diff && paths.length === 2, - extensionHomePath: normalizePath(argv.extensionHomePath), - extensionDevelopmentPath: normalizePath(argv.extensionDevelopmentPath), - extensionTestsPath: normalizePath(argv.extensionTestsPath), - 'disable-extensions': argv['disable-extensions'], - 'open-url': argv['open-url'], - locale: argv.locale, - wait: argv.wait - }); - } + // Update environment + args._ = paths; + args.diff = args.diff && paths.length === 2; + + return args; } -function parsePathArguments(args: string[], gotoLineMode?: boolean): string[] { +function doValidatePaths(args: string[], gotoLineMode?: boolean): string[] { const cwd = process.env['VSCODE_CWD'] || process.cwd(); const result = args.map(arg => { let pathCandidate = String(arg); - let parsedPath: IParsedPath; + let parsedPath: IPathWithLineAndColumn; if (gotoLineMode) { parsedPath = parseLineAndColumnAware(pathCandidate); pathCandidate = parsedPath.path; @@ -86,7 +57,7 @@ function parsePathArguments(args: string[], gotoLineMode?: boolean): string[] { if (gotoLineMode) { parsedPath.path = realPath; - return toLineAndColumnPath(parsedPath); + return toPath(parsedPath); } return realPath; @@ -120,17 +91,13 @@ function preparePath(cwd: string, p: string): string { return p; } -function normalizePath(p?: string): string { - return p ? path.normalize(p) : p; -} - -export interface IParsedPath { +export interface IPathWithLineAndColumn { path: string; line?: number; column?: number; } -export function parseLineAndColumnAware(rawPath: string): IParsedPath { +export function parseLineAndColumnAware(rawPath: string): IPathWithLineAndColumn { const segments = rawPath.split(':'); // C:\file.txt:: let path: string; @@ -159,15 +126,15 @@ export function parseLineAndColumnAware(rawPath: string): IParsedPath { }; } -function toLineAndColumnPath(parsedPath: IParsedPath): string { - const segments = [parsedPath.path]; +function toPath(p: IPathWithLineAndColumn): string { + const segments = [p.path]; - if (types.isNumber(parsedPath.line)) { - segments.push(String(parsedPath.line)); + if (types.isNumber(p.line)) { + segments.push(String(p.line)); } - if (types.isNumber(parsedPath.column)) { - segments.push(String(parsedPath.column)); + if (types.isNumber(p.column)) { + segments.push(String(p.column)); } return segments.join(':'); diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index d2a454dcac8..d4a9327154f 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -18,7 +18,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { IStorageService } from 'vs/code/electron-main/storage'; import { IPath, VSCodeWindow, ReadyState, IWindowConfiguration, IWindowState as ISingleWindowState, defaultWindowState, IWindowSettings } from 'vs/code/electron-main/window'; import { ipcMain as ipc, app, screen, crashReporter, BrowserWindow, dialog } from 'electron'; -import { IEnvService, IParsedPath, parseLineAndColumnAware } from 'vs/code/electron-main/env'; +import { IPathWithLineAndColumn, parseLineAndColumnAware } from 'vs/code/electron-main/paths'; import { ILifecycleService } from 'vs/code/electron-main/lifecycle'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IUpdateService, IUpdate } from 'vs/code/electron-main/update-manager'; @@ -163,7 +163,6 @@ export class WindowsManager implements IWindowsService { @IInstantiationService private instantiationService: IInstantiationService, @ILogService private logService: ILogService, @IStorageService private storageService: IStorageService, - @IEnvService private envService: IEnvService, @IEnvironmentService private environmentService: IEnvironmentService, @ILifecycleService private lifecycleService: ILifecycleService, @IUpdateService private updateService: IUpdateService, @@ -222,7 +221,7 @@ export class WindowsManager implements IWindowsService { // Handle paths delayed in case more are coming! runningTimeout = setTimeout(() => { - this.open({ cli: this.envService.cliArgs, pathsToOpen: macOpenFiles, preferNewWindow: true /* dropping on the dock prefers to open in a new window */ }); + this.open({ cli: this.environmentService.args, pathsToOpen: macOpenFiles, preferNewWindow: true /* dropping on the dock prefers to open in a new window */ }); macOpenFiles = []; runningTimeout = null; }, 100); @@ -238,7 +237,7 @@ export class WindowsManager implements IWindowsService { this.logService.log('IPC#vscode-windowOpen: ', paths); if (paths && paths.length) { - this.open({ cli: this.envService.cliArgs, pathsToOpen: paths, forceNewWindow: forceNewWindow }); + this.open({ cli: this.environmentService.args, pathsToOpen: paths, forceNewWindow: forceNewWindow }); } }); @@ -277,7 +276,7 @@ export class WindowsManager implements IWindowsService { const win = this.getWindowById(windowId); if (win) { - this.open({ cli: this.envService.cliArgs, forceEmpty: true, windowToUse: win }); + this.open({ cli: this.environmentService.args, forceEmpty: true, windowToUse: win }); } }); @@ -862,7 +861,7 @@ export class WindowsManager implements IWindowsService { return null; } - let parsedPath: IParsedPath; + let parsedPath: IPathWithLineAndColumn; if (gotoLineMode) { parsedPath = parseLineAndColumnAware(anyPath); anyPath = parsedPath.path; @@ -1107,7 +1106,7 @@ export class WindowsManager implements IWindowsService { private doPickAndOpen(options: INativeOpenDialogOptions): void { this.getFileOrFolderPaths(options, (paths: string[]) => { if (paths && paths.length) { - this.open({ cli: this.envService.cliArgs, pathsToOpen: paths, forceNewWindow: options.forceNewWindow }); + this.open({ cli: this.environmentService.args, pathsToOpen: paths, forceNewWindow: options.forceNewWindow }); } }); } @@ -1213,7 +1212,7 @@ export class WindowsManager implements IWindowsService { } public openNewWindow(): void { - this.open({ cli: this.envService.cliArgs, forceNewWindow: true, forceEmpty: true }); + this.open({ cli: this.environmentService.args, forceNewWindow: true, forceEmpty: true }); } public sendToFocused(channel: string, ...args: any[]): void { diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index f3bb9a38948..97bf71f3c34 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -79,9 +79,12 @@ export class EnvironmentService implements IEnvironmentService { @memoize get extensionsPath(): string { return path.normalize(this._args.extensionHomePath || path.join(this.userHome, 'extensions')); } - get extensionDevelopmentPath(): string { return this._args.extensionDevelopmentPath; } + @memoize + get extensionDevelopmentPath(): string { return this._args.extensionDevelopmentPath ? path.normalize(this._args.extensionDevelopmentPath) : this._args.extensionDevelopmentPath; } + + @memoize + get extensionTestsPath(): string { return this._args.extensionTestsPath ? path.normalize(this._args.extensionTestsPath) : this._args.extensionTestsPath; } - get extensionTestsPath(): string { return this._args.extensionTestsPath; } get disableExtensions(): boolean { return this._args['disable-extensions']; } @memoize -- GitLab