cleaner args validation

fixes #10764
This commit is contained in:
Joao Moreno
2016-08-22 11:56:03 +02:00
parent e5e9e665e8
commit c2da84de3a
5 changed files with 110 additions and 59 deletions

View File

@@ -5,6 +5,7 @@
import * as os from 'os';
import * as minimist from 'minimist';
import * as assert from 'assert';
import { firstIndex } from 'vs/base/common/arrays';
import { localize } from 'vs/nls';
@@ -71,22 +72,47 @@ const options: minimist.Opts = {
}
};
function validate(args: ParsedArgs): ParsedArgs {
if (args.goto) {
args._.forEach(arg => assert(/^[^:]+(:\d+){0,2}$/.test(arg), localize('gotoValidation', "Arguments in `--goto` mode should be in the format of `FILE(:LINE(:COLUMN))`.")));
}
return args;
}
function stripAppPath(argv: string[]): string[] {
const index = firstIndex(argv, a => !/^-/.test(a));
if (index > -1) {
return [...argv.slice(0, index), ...argv.slice(index + 1)];
}
}
/**
* Use this to parse raw code process.argv such as: `Electron . --verbose --wait`
*/
export function parseMainProcessArgv(processArgv: string[]): ParsedArgs {
const [, ...args] = processArgv;
let [, ...args] = processArgv;
// If dev, remove the first non-option argument: it's the app location
if (process.env['VSCODE_DEV']) {
const index = firstIndex(args, a => !/^-/.test(a));
if (index > -1) {
args.splice(index, 1);
}
args = stripAppPath(args);
}
return parseArgs(args);
return validate(parseArgs(args));
}
/**
* Use this to parse raw code CLI process.argv such as: `Electron cli.js . --verbose --wait`
*/
export function parseCLIProcessArgv(processArgv: string[]): ParsedArgs {
let [,, ...args] = processArgv;
if (process.env['VSCODE_DEV']) {
args = stripAppPath(args);
}
return validate(parseArgs(args));
}
/**

View File

@@ -6,7 +6,7 @@
import { spawn } from 'child_process';
import { TPromise } from 'vs/base/common/winjs.base';
import { assign } from 'vs/base/common/objects';
import { parseArgs, buildHelpMessage, ParsedArgs } from 'vs/code/node/argv';
import { parseCLIProcessArgv, buildHelpMessage, ParsedArgs } from 'vs/code/node/argv';
import pkg from 'vs/platform/package';
function shouldSpawnCliProcess(argv: ParsedArgs): boolean {
@@ -17,16 +17,23 @@ interface IMainCli {
main: (argv: ParsedArgs) => TPromise<void>;
}
export function main(args: string[]): TPromise<void> {
const argv = parseArgs(args);
export function main(argv: string[]): TPromise<void> {
let args: ParsedArgs;
if (argv.help) {
try {
args = parseCLIProcessArgv(argv);
} catch (err) {
console.error(err.message);
return TPromise.as(null);
}
if (args.help) {
console.log(buildHelpMessage(pkg.version));
} else if (argv.version) {
} else if (args.version) {
console.log(pkg.version);
} else if (shouldSpawnCliProcess(argv)) {
} else if (shouldSpawnCliProcess(args)) {
const mainCli = new TPromise<IMainCli>(c => require(['vs/code/node/cliProcessMain'], c));
return mainCli.then(cli => cli.main(argv));
return mainCli.then(cli => cli.main(args));
} else {
const env = assign({}, process.env, {
// this will signal Code that it was spawned from this module
@@ -39,18 +46,18 @@ export function main(args: string[]): TPromise<void> {
detached: true,
env,
};
if (!argv.verbose) {
if (!args.verbose) {
options['stdio'] = 'ignore';
}
const child = spawn(process.execPath, args, options);
const child = spawn(process.execPath, argv.slice(2), options);
if (argv.verbose) {
if (args.verbose) {
child.stdout.on('data', (data) => console.log(data.toString('utf8').trim()));
child.stderr.on('data', (data) => console.log(data.toString('utf8').trim()));
}
if (argv.wait || argv.verbose) {
if (args.wait || args.verbose) {
return new TPromise<void>(c => child.once('exit', () => c(null)));
}
}
@@ -58,7 +65,7 @@ export function main(args: string[]): TPromise<void> {
return TPromise.as(null);
}
main(process.argv.slice(2))
main(process.argv)
.then(() => process.exit(0))
.then(null, err => {
console.error(err.stack ? err.stack : err);

View File

@@ -7,7 +7,7 @@ import { localize } from 'vs/nls';
import product from 'vs/platform/product';
import pkg from 'vs/platform/package';
import * as path from 'path';
import { parseArgs, ParsedArgs } from 'vs/code/node/argv';
import { ParsedArgs } from 'vs/code/node/argv';
import { TPromise } from 'vs/base/common/winjs.base';
import { sequence } from 'vs/base/common/async';
import { IPager } from 'vs/base/common/paging';
@@ -145,7 +145,7 @@ const eventPrefix = 'monacoworkbench';
export function main(argv: ParsedArgs): TPromise<void> {
const services = new ServiceCollection();
services.set(IEnvironmentService, new SyncDescriptor(EnvironmentService, parseArgs(process.argv), process.execPath));
services.set(IEnvironmentService, new SyncDescriptor(EnvironmentService, argv, process.execPath));
const instantiationService: IInstantiationService = new InstantiationService(services);