UNPKG

browsertime

Version:

Get performance metrics from your web page using Browsertime.

175 lines (164 loc) 5.12 kB
/*eslint no-console: 0*/ // Help-topic dispatch for the Browsertime CLI. // // Browsertime declares ~250 options in one big yargs chain, with each // option carrying an inline `group: '<topic>'` field. The unfiltered // --help dump is overwhelming; this module lets users say: // // browsertime --help -> curated set of common options // browsertime --help <topic> -> only that topic // browsertime --help-all -> the full historical dump // // We intercept the yargs instance's .option() call to capture each // key's topic from the inline `group` field, so the cli.js chain // doesn't have to change shape. // Curated set of "everyday" options the default --help should show. // Keep this list short -- anything missing is one --help <topic> away. const COMMON_KEYS = new Set([ // common everyday flags 'browser', 'b', 'iterations', 'n', 'video', 'visualMetrics', 'speedIndex', 'docker', 'preURL', 'headless', 'connectivity.profile', 'c', 'connectivity.engine', 'mobile', 'resultDir', 'cpu', // meta 'config', 'help', 'h', 'verbose', 'v', 'version', 'V' ]); // Meta-flags that always stay visible regardless of mode. const ALWAYS_KEEP = new Set([ 'help', 'h', 'version', 'V', 'config', 'verbose', 'v' ]); const DOCS_URL = 'https://www.sitespeed.io/documentation/browsertime/'; // Parse the raw arg list, detect help intent, and return a cleaned arg // list with `--help-all` / `--help <topic>` collapsed to a plain // `--help` so yargs still triggers its normal help+exit flow. // // Returns { mode, topic, args } where mode is one of: // 'none' -> no --help passed // 'default' -> plain --help, show the curated common subset // 'topic' -> --help <topic>, show only that topic // 'all' -> --help-all (or --help all), show everything export function classifyHelp(rawArgs) { const cleaned = []; let mode = 'none'; let topic; for (let i = 0; i < rawArgs.length; i++) { const a = rawArgs[i]; if (a === '--help-all') { mode = 'all'; cleaned.push('--help'); continue; } if (a === '--help' || a === '-h' || a === '--help=true') { const next = rawArgs[i + 1]; if (next && !next.startsWith('-')) { if (next === 'all') { mode = 'all'; i++; } else { mode = 'topic'; topic = next; i++; } } else if (mode === 'none') { mode = 'default'; } cleaned.push('--help'); continue; } cleaned.push(a); } return { mode, topic, args: cleaned }; } // Wrap a yargs instance so every subsequent .option(key, def) call also // records `key` under `def.group` in the returned Map. Browsertime's // option chain already carries inline `group: '<topic>'` annotations, // so no chain edits are needed. export function captureTopics(yargsInstance) { const topicKeys = new Map(); const originalOption = yargsInstance.option.bind(yargsInstance); yargsInstance.option = function (key, def) { if (def && def.group) { const list = topicKeys.get(def.group) || []; list.push(key); topicKeys.set(def.group, list); } return originalOption(key, def); }; return topicKeys; } // Build the epilog (footer) shown under --help, varying by mode. export function buildEpilog(mode, topic, topicNames) { if (mode === 'all' || mode === 'none') { return `Read the docs at ${DOCS_URL}`; } if (mode === 'topic') { return [ `Showing only the "${topic}" options.`, `Run with --help-all for the full reference, or --help to see common options.`, `Read the docs at ${DOCS_URL}` ].join('\n'); } // default const topics = topicNames.join(', '); return [ 'Topics (use `browsertime --help <topic>`):', ' ' + topics, '', 'Run with --help-all to see every option, or read the docs at ' + DOCS_URL ].join('\n'); } // Apply the topic filter by calling yargs.hide() on every key not in // the set we want to display. Returns true if filtering was applied. export function applyHelpFilter(yargsInstance, mode, topic, topicKeys) { if (mode === 'none' || mode === 'all') return false; let keep; if (mode === 'topic') { if (!topicKeys.has(topic)) { console.error(`Unknown help topic: ${topic}`); console.error('Available topics: ' + [...topicKeys.keys()].join(', ')); // CLI dispatch: bailing out here is intentional (deliberate "no // such topic" exit code), not an error to bubble up the stack. // eslint-disable-next-line unicorn/no-process-exit process.exit(2); } // Topic mode = just the topic. No COMMON_KEYS floor here -- topic // views should focus on the topic, not re-render common stuff // that's one --help away. keep = new Set(topicKeys.get(topic)); } else { // default keep = COMMON_KEYS; } const allKeys = Object.keys(yargsInstance.getOptions().key); for (const k of allKeys) { if (ALWAYS_KEEP.has(k)) continue; if (!keep.has(k)) { yargsInstance.hide(k); } } return true; }