mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-27 20:13:32 +01:00
move args, cli, sharedProcessMain to code
This commit is contained in:
@@ -1,92 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as os from 'os';
|
||||
import * as minimist from 'minimist';
|
||||
import pkg from 'vs/code/node/package';
|
||||
|
||||
export interface ParsedArgs extends minimist.ParsedArgs {
|
||||
help: boolean;
|
||||
version: boolean;
|
||||
wait: boolean;
|
||||
diff: boolean;
|
||||
goto: boolean;
|
||||
'new-window': boolean;
|
||||
'reuse-window': boolean;
|
||||
locale: string;
|
||||
'user-data-dir': string;
|
||||
performance: boolean;
|
||||
verbose: boolean;
|
||||
logExtensionHostCommunication: boolean;
|
||||
debugBrkFileWatcherPort: string;
|
||||
'disable-extensions': boolean;
|
||||
extensionHomePath: string;
|
||||
extensionDevelopmentPath: string;
|
||||
extensionTestsPath: string;
|
||||
timestamp: string;
|
||||
debugBrkPluginHost: string;
|
||||
debugPluginHost: string;
|
||||
}
|
||||
|
||||
const options: minimist.Opts = {
|
||||
string: [
|
||||
'locale',
|
||||
'user-data-dir',
|
||||
'extensionHomePath',
|
||||
'extensionDevelopmentPath',
|
||||
'extensionTestsPath',
|
||||
'timestamp'
|
||||
],
|
||||
boolean: [
|
||||
'help',
|
||||
'version',
|
||||
'wait',
|
||||
'diff',
|
||||
'goto',
|
||||
'new-window',
|
||||
'reuse-window',
|
||||
'performance',
|
||||
'verbose',
|
||||
'logExtensionHostCommunication',
|
||||
'disable-extensions'
|
||||
],
|
||||
alias: {
|
||||
help: 'h',
|
||||
version: 'v',
|
||||
wait: 'w',
|
||||
diff: 'd',
|
||||
goto: 'g',
|
||||
'new-window': 'n',
|
||||
'reuse-window': 'r',
|
||||
performance: 'p',
|
||||
'disable-extensions': 'disableExtensions'
|
||||
}
|
||||
};
|
||||
|
||||
export function parseArgs(args: string[]) {
|
||||
return minimist(args, options) as ParsedArgs;
|
||||
}
|
||||
|
||||
const executable = 'code' + (os.platform() === 'win32' ? '.exe' : '');
|
||||
const indent = ' ';
|
||||
export const helpMessage = `Visual Studio Code v${ pkg.version }
|
||||
|
||||
Usage: ${ executable } [arguments] [paths...]
|
||||
|
||||
Options:
|
||||
${ indent }-d, --diff Open a diff editor. Requires to pass two file paths
|
||||
${ indent } as arguments.
|
||||
${ indent }--disable-extensions Disable all installed extensions.
|
||||
${ indent }-g, --goto Open the file at path at the line and column (add
|
||||
${ indent } :line[:column] to path).
|
||||
${ indent }-h, --help Print usage.
|
||||
${ indent }--locale <locale> The locale to use (e.g. en-US or zh-TW).
|
||||
${ indent }-n, --new-window Force a new instance of Code.
|
||||
${ indent }-r, --reuse-window Force opening a file or folder in the last active
|
||||
${ indent } window.
|
||||
${ indent }--user-data-dir <dir> Specifies the directory that user data is kept in,
|
||||
${ indent } useful when running as root.
|
||||
${ indent }-v, --version Print version.
|
||||
${ indent }-w, --wait Wait for the window to be closed before returning.`;
|
||||
@@ -1,41 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { spawn } from 'child_process';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import { parseArgs, helpMessage } from './argv';
|
||||
import pkg from 'vs/code/node/package';
|
||||
|
||||
export function main(args: string[]) {
|
||||
const argv = parseArgs(args);
|
||||
|
||||
if (argv.help) {
|
||||
console.log(helpMessage);
|
||||
} else if (argv.version) {
|
||||
console.log(pkg.version);
|
||||
} else {
|
||||
const env = assign({}, process.env, {
|
||||
// this will signal Code that it was spawned from this module
|
||||
'VSCODE_CLI': '1',
|
||||
'ELECTRON_NO_ATTACH_CONSOLE': '1'
|
||||
});
|
||||
delete env['ATOM_SHELL_INTERNAL_RUN_AS_NODE'];
|
||||
|
||||
const child = spawn(process.execPath, args, {
|
||||
detached: true,
|
||||
stdio: 'ignore',
|
||||
env
|
||||
});
|
||||
|
||||
if (argv.wait) {
|
||||
child.on('exit', process.exit);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
main(process.argv.slice(2));
|
||||
@@ -18,7 +18,7 @@ import uri from 'vs/base/common/uri';
|
||||
import types = require('vs/base/common/types');
|
||||
import {ServiceIdentifier, createDecorator} from 'vs/platform/instantiation/common/instantiation';
|
||||
import product, {IProductConfiguration} from 'vs/code/node/product';
|
||||
import { parseArgs } from './argv';
|
||||
import { parseArgs } from 'vs/code/node/argv';
|
||||
|
||||
export interface IProcessEnvironment {
|
||||
[key: string]: string;
|
||||
|
||||
@@ -38,7 +38,7 @@ function _spawnSharedProcess(envService: IEnvironmentService, updateManager: IUp
|
||||
// Make sure the nls configuration travels to the shared process.
|
||||
const opts = {
|
||||
env: assign(assign({}, process.env), {
|
||||
AMD_ENTRYPOINT: 'vs/code/electron-main/sharedProcessMain'
|
||||
AMD_ENTRYPOINT: 'vs/code/node/sharedProcessMain'
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as fs from 'fs';
|
||||
import platform = require('vs/base/common/platform');
|
||||
import { serve, Server, connect } from 'vs/base/parts/ipc/node/ipc.net';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IConfiguration } from 'vs/platform/workspace/common/workspace';
|
||||
import { WorkspaceContextService } from 'vs/workbench/services/workspace/common/contextService';
|
||||
import { EventService } from 'vs/platform/event/common/eventService';
|
||||
import { ExtensionsChannel } from 'vs/workbench/parts/extensions/common/extensionsIpc';
|
||||
import { ExtensionsService } from 'vs/workbench/parts/extensions/node/extensionsService';
|
||||
|
||||
interface IInitData {
|
||||
configuration: IConfiguration;
|
||||
contextServiceOptions: { settings: any };
|
||||
}
|
||||
|
||||
function quit(err?: Error) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
process.exit(err ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Plan B is to kill oneself if one's parent dies. Much drama.
|
||||
*/
|
||||
function setupPlanB(parentPid: number): void {
|
||||
setInterval(function () {
|
||||
try {
|
||||
process.kill(parentPid, 0); // throws an exception if the main process doesn't exist anymore.
|
||||
} catch (e) {
|
||||
process.exit();
|
||||
}
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
function main(server: Server, initData: IInitData): void {
|
||||
const eventService = new EventService();
|
||||
const contextService = new WorkspaceContextService(eventService, null, initData.configuration, initData.contextServiceOptions);
|
||||
const extensionService = new ExtensionsService(contextService);
|
||||
const channel = new ExtensionsChannel(extensionService);
|
||||
|
||||
server.registerChannel('extensions', channel);
|
||||
|
||||
// eventually clean up old extensions
|
||||
setTimeout(() => extensionService.removeDeprecatedExtensions(), 5000);
|
||||
}
|
||||
|
||||
function setupIPC(hook: string): TPromise<Server> {
|
||||
function setup(retry: boolean): TPromise<Server> {
|
||||
return serve(hook).then(null, err => {
|
||||
if (!retry || platform.isWindows || err.code !== 'EADDRINUSE') {
|
||||
return TPromise.wrapError(err);
|
||||
}
|
||||
|
||||
// should retry, not windows and eaddrinuse
|
||||
|
||||
return connect(hook).then(
|
||||
client => {
|
||||
// we could connect to a running instance. this is not good, abort
|
||||
client.dispose();
|
||||
return TPromise.wrapError(new Error('There is an instance already running.'));
|
||||
},
|
||||
err => {
|
||||
// it happens on Linux and OS X that the pipe is left behind
|
||||
// let's delete it, since we can't connect to it
|
||||
// and the retry the whole thing
|
||||
try {
|
||||
fs.unlinkSync(hook);
|
||||
} catch (e) {
|
||||
return TPromise.wrapError(new Error('Error deleting the shared ipc hook.'));
|
||||
}
|
||||
|
||||
return setup(false);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return setup(true);
|
||||
}
|
||||
|
||||
function handshake(): TPromise<IInitData> {
|
||||
return new TPromise<IInitData>((c, e) => {
|
||||
process.once('message', c);
|
||||
process.once('error', e);
|
||||
process.send('hello');
|
||||
});
|
||||
}
|
||||
|
||||
TPromise.join<any>([setupIPC(process.env['VSCODE_SHARED_IPC_HOOK']), handshake()])
|
||||
.then(r => main(r[0], r[1]))
|
||||
.then(() => setupPlanB(process.env['VSCODE_PID']))
|
||||
.done(null, quit);
|
||||
Reference in New Issue
Block a user