Skip to content

Commit

Permalink
Remove yargs-unparser dep; avoid loading yargs in spawned process
Browse files Browse the repository at this point in the history
Pass parsed args object to spawned process as JSON string.
  • Loading branch information
cspotcode committed Mar 14, 2019
1 parent 0098147 commit 654fee2
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 89 deletions.
9 changes: 4 additions & 5 deletions bin/mocha
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,20 @@

const {deprecate, warn} = require('../lib/utils');
const {spawn} = require('child_process');
const {loadOptions} = require('../lib/cli/options');
const {parseArgv} = require('../lib/cli/cli');
const {
unparseNodeFlags,
isNodeFlag,
impliesNoTimeouts
} = require('../lib/cli/node-flags');
const unparse = require('yargs-unparser');
const debug = require('debug')('mocha:cli:mocha');
const {aliases} = require('../lib/cli/run-option-metadata');
const nodeEnv = require('node-environment-flags');

const mochaPath = require.resolve('./_mocha');
const mochaArgs = {};
const nodeArgs = {};

const opts = loadOptions(process.argv.slice(2));
const opts = parseArgv(process.argv.slice(2));
debug('loaded opts', opts);

/**
Expand Down Expand Up @@ -123,7 +121,8 @@ debug('final node args', nodeArgs);
const args = [].concat(
unparseNodeFlags(nodeArgs),
mochaPath,
unparse(mochaArgs, {alias: aliases})
'--preParsedJsonOptions',
JSON.stringify(mochaArgs)
);

debug(`exec ${process.execPath} w/ args:`, args);
Expand Down
41 changes: 35 additions & 6 deletions lib/cli/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@

const debug = require('debug')('mocha:cli:cli');
const symbols = require('log-symbols');
const yargs = require('yargs');
const path = require('path');
const {loadOptions, YARGS_PARSER_CONFIG} = require('./options');
const commands = require('./commands');
const ansi = require('ansi-colors');
const {repository, homepage, version, gitter} = require('../../package.json');

Expand All @@ -32,7 +29,33 @@ exports.main = (argv = process.argv.slice(2)) => {

Error.stackTraceLimit = Infinity; // configurable via --stack-trace-limit?

yargs
const args = exports.parseArgv(argv);
const {handler} = require(`./${args.command.name}`);
args.command = null;
handler(args);
};

exports.yargsParse = function(argv) {
const {loadOptions} = require('./options');
return exports
.createYargs()
.parse(argv, Object.assign(loadOptions(argv), {command: {}}));
};

exports.showUsageAndError = function(error) {
exports
.createYargs()
.check(() => {
throw error;
})
.parse([]);
};

exports.createYargs = function() {
const yargs = require('yargs');
const {YARGS_PARSER_CONFIG} = require('./options');
const commands = require('./commands');
return yargs
.scriptName('mocha')
.command(commands.run)
.command(commands.init)
Expand All @@ -59,8 +82,14 @@ exports.main = (argv = process.argv.slice(2)) => {
Docs: ${ansi.yellow(homepage)}
`
)
.parserConfiguration(YARGS_PARSER_CONFIG)
.parse(argv, loadOptions(argv));
.parserConfiguration(YARGS_PARSER_CONFIG);
};

exports.parseArgv = function(argv = process.argv.slice(2)) {
if (argv.length === 2 && argv[0] === '--preParsedJsonOptions') {
return JSON.parse(argv[1]);
}
return exports.yargsParse(argv);
};

// allow direct execution
Expand Down
6 changes: 6 additions & 0 deletions lib/cli/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
const fs = require('fs');
const path = require('path');
const mkdirp = require('mkdirp');
const debug = require('debug')('mocha:cli:init');

exports.command = 'init <path>';

Expand All @@ -22,6 +23,11 @@ exports.builder = yargs =>
});

exports.handler = argv => {
debug('post-yargs config', argv);
if (argv.command) {
argv.command.name = 'init';
return;
}
const destdir = argv.path;
const srcdir = path.join(__dirname, '..', '..');
mkdirp.sync(destdir);
Expand Down
26 changes: 16 additions & 10 deletions lib/cli/node-flags.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
*/

const nodeFlags = require('node-environment-flags');
const unparse = require('yargs-unparser');

/**
* These flags are considered "debug" flags.
Expand Down Expand Up @@ -74,13 +73,20 @@ exports.impliesNoTimeouts = flag => debugFlags.has(flag);
* @private
*/
exports.unparseNodeFlags = opts => {
var args = unparse(opts);
return args.length
? args
.join(' ')
.split(/\b/)
.map(arg => (arg === ' ' ? '=' : arg))
.join('')
.split(' ')
: [];
const args = [];
for (let k in opts) {
if (Object.prototype.hasOwnProperty.call(opts, k)) {
args.push(map(opts[k], k));
}
}
return args;
function map(value, key) {
if (value === true) {
return `--${key}`;
} else if (value === false) {
// TODO
} else {
return `--${key}=${value}`;
}
}
};
18 changes: 13 additions & 5 deletions lib/cli/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,11 +274,6 @@ exports.builder = yargs =>
);
}

// load requires first, because it can impact "plugin" validation
handleRequires(argv.require);
validatePlugin(argv, 'reporter', Mocha.reporters);
validatePlugin(argv, 'ui', Mocha.interfaces);

return true;
})
.array(types.array)
Expand All @@ -289,6 +284,19 @@ exports.builder = yargs =>

exports.handler = argv => {
debug('post-yargs config', argv);
if (argv.command) {
argv.command.name = 'run';
return;
}
try {
// load requires first, because it can impact "plugin" validation
handleRequires(argv.require);
validatePlugin(argv, 'reporter', Mocha.reporters);
validatePlugin(argv, 'ui', Mocha.interfaces);
} catch (e) {
require('./cli').showUsageAndError(e);
}

const mocha = new Mocha(argv);
const files = handleFiles(argv);

Expand Down
66 changes: 6 additions & 60 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -513,8 +513,7 @@
"which": "1.3.1",
"wide-align": "1.1.3",
"yargs": "13.2.2",
"yargs-parser": "13.0.0",
"yargs-unparser": "1.5.0"
"yargs-parser": "13.0.0"
},
"devDependencies": {
"@11ty/eleventy": "^0.7.1",
Expand Down
9 changes: 8 additions & 1 deletion test/node-unit/cli/run.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@ describe('command', function() {
describe('run', function() {
describe('builder', function() {
const IGNORED_OPTIONS = new Set(['help', 'version']);
const options = builder(require('yargs')).getOptions();
const yargs = require('yargs');
// Without doing this first, yargs will throw an error when we call `.positional()` below.
yargs
.command('foo', 'bar', yargs => {
return yargs;
})
.parse(['foo']);
const options = builder(yargs).getOptions();
['number', 'string', 'boolean', 'array'].forEach(type => {
describe(`${type} type`, function() {
Array.from(new Set(options[type])).forEach(option => {
Expand Down

0 comments on commit 654fee2

Please sign in to comment.