cli(flags): accept comma-separated array values (#8933)

This commit is contained in:
cjamcl 2019-05-22 15:09:31 -07:00 коммит произвёл Brendan Kenny
Родитель 44054604f3
Коммит 066984d1e9
2 изменённых файлов: 65 добавлений и 2 удалений

Просмотреть файл

@ -11,14 +11,26 @@ const yargs = require('yargs');
const pkg = require('../package.json');
const printer = require('./printer.js');
/**
* Remove in Node 11 - [].flatMap
* @param {Array<Array<string>>} arr
* @return {string[]}
*/
function flatten(arr) {
/** @type {string[]} */
const result = [];
return result.concat(...arr);
}
/**
* @param {string=} manualArgv
* @return {LH.CliFlags}
*/
function getFlags(manualArgv) {
// @ts-ignore yargs() is incorrectly typed as not returning itself
// @ts-ignore yargs() is incorrectly typed as not accepting a single string.
const y = manualArgv ? yargs(manualArgv) : yargs;
return y.help('help')
// Intentionally left as type `any` because @types/yargs doesn't chain correctly.
const argv = y.help('help')
.version(() => pkg.version)
.showHelpOnFail(false, 'Specify --help for available options')
@ -46,6 +58,9 @@ function getFlags(manualArgv) {
.example(
'lighthouse <url> --extra-headers=./path/to/file.json',
'Path to JSON file of HTTP Header key/value pairs to send in requests')
.example(
'lighthouse <url> --only-categories=performance,pwa',
'Only run specific categories.')
// List of options
.group(['verbose', 'quiet'], 'Logging:')
@ -171,6 +186,29 @@ function getFlags(manualArgv) {
'For more information on Lighthouse, see https://developers.google.com/web/tools/lighthouse/.')
.wrap(yargs.terminalWidth())
.argv;
// Support comma-separated values for some array flags by splitting on any ',' found.
/** @type {Array<keyof LH.CliFlags>} */
const arrayKeysThatSupportCsv = [
'onlyAudits',
'onlyCategories',
'output',
'plugins',
'skipAudits',
];
arrayKeysThatSupportCsv.forEach(key => {
// If a key is defined as an array in yargs, the value (if provided)
// will always be a string array. However, we keep argv and input as any,
// since assigning back to argv as string[] would be unsound for enums,
// for example: output is LH.OutputMode[].
const input = argv[key];
// Truthy check is necessary. isArray convinces TS that this is an array.
if (Array.isArray(input)) {
argv[key] = flatten(input.map(value => value.split(',')));
}
});
return argv;
}
module.exports = {

Просмотреть файл

@ -28,4 +28,29 @@ describe('CLI bin', function() {
assert.ok(optionsWithDescriptions.includes(opt), `cli option '${opt}' has no description`);
});
});
it('array values support csv when appropriate', () => {
const flags = getFlags([
'http://www.example.com',
'--only-categories=performance,seo',
'--skipAudits=unused-javascript,redirects',
'--skipAudits=bootup-time',
].join(' '));
expect(flags.onlyCategories).toEqual(['performance', 'seo']);
expect(flags.skipAudits).toEqual(['unused-javascript', 'redirects', 'bootup-time']);
});
it('array values do not support csv when appropriate', () => {
const flags = getFlags([
'http://www.example.com',
'--chrome-flags="--window-size 800,600"',
'--chrome-flags="--enabled-features=NetworkService,VirtualTime"',
'--blockedUrlPatterns=.*x,y\\.png',
].join(' '));
expect(flags.chromeFlags).toEqual([
'--window-size 800,600',
'--enabled-features=NetworkService,VirtualTime',
]);
expect(flags.blockedUrlPatterns).toEqual(['.*x,y\\.png']);
});
});