Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cli: accept csv for array values #8933

Merged
merged 13 commits into from
May 22, 2019
42 changes: 40 additions & 2 deletions lighthouse-cli/cli-flags.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,26 @@ const yargs = require('yargs');
const pkg = require('../package.json');
const printer = require('./printer');

/**
* 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')

Expand Down Expand Up @@ -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:')
Expand Down Expand Up @@ -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 = {
Expand Down
25 changes: 25 additions & 0 deletions lighthouse-cli/test/cli/cli-flags-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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']);
});
});