From c2ba788a6103ef8d1798703919e5452544d86b3a Mon Sep 17 00:00:00 2001 From: Liang Gong Date: Tue, 3 Dec 2024 11:33:55 -0800 Subject: [PATCH] fix(cli): better command line helper text content and format Summary: ## Before {F1968819378} ## After {F1968819329} Differential Revision: D66548359 fbshipit-source-id: b54289477f782dd64e003e3e7a808f6281f18728 --- .../cli/src/commands/helper/HelperCommand.ts | 4 +- .../cli/src/commands/helper/lib/DocUtils.ts | 66 +++++++++++++++++++ .../src/options/HeapAnalysisOutputOption.ts | 8 ++- website/docs/cli/CLI-commands.md | 14 ++-- 4 files changed, 82 insertions(+), 10 deletions(-) diff --git a/packages/cli/src/commands/helper/HelperCommand.ts b/packages/cli/src/commands/helper/HelperCommand.ts index b3427d69d..a6c24a24f 100644 --- a/packages/cli/src/commands/helper/HelperCommand.ts +++ b/packages/cli/src/commands/helper/HelperCommand.ts @@ -220,8 +220,8 @@ export default class HelperCommand extends BaseCommand { const cmd = docUtils.generateExampleCommand(name, example, { descriptionAsBashComment: false, }); - let msg = `${indent}${cmd}`; - msg += `\n${indent}${desc}`; + let msg = docUtils.indentText(cmd, indent); + msg += `\n${docUtils.indentText(desc, indent)}`; if (options.printOptions && cmdDoc.length > 0) { const cmdDocBlock = alignTextInBlock(cmdDoc, { diff --git a/packages/cli/src/commands/helper/lib/DocUtils.ts b/packages/cli/src/commands/helper/lib/DocUtils.ts index 665c9d6b6..2e63afda6 100644 --- a/packages/cli/src/commands/helper/lib/DocUtils.ts +++ b/packages/cli/src/commands/helper/lib/DocUtils.ts @@ -54,6 +54,72 @@ function exampleFromCliOptionString( return `memlab ${command} ${cliExample.trim()}`; } +function getCLIWidth() { + return process.stdout.columns || 80; // Default to 80 if undefined +} + +function indentText(description: string, indent: string): string { + const cliWidth = getCLIWidth(); + const availableWidth = cliWidth - indent.length; + const lines: Array = []; + + // Split the description by \n to handle existing line breaks + const descriptionLines = description.split('\n'); + + descriptionLines.forEach(descLine => { + const words = descLine.split(/\s+/); + let line = ''; + for (let i = 0; i < words.length; i++) { + const word = words[i]; + if (line.length === 0) { + // Start a new line with the word + if (word.length > availableWidth) { + // The word itself is longer than the available width + // Split the word + let start = 0; + while (start < word.length) { + const part = word.substring(start, start + availableWidth); + lines.push(indent + part); + start += availableWidth; + } + line = ''; + } else { + line = word; + } + } else { + const potentialLine = line + ' ' + word; + if (potentialLine.length <= availableWidth) { + line = potentialLine; + } else { + // Line is full, push it and start new line + lines.push(indent + line); + if (word.length > availableWidth) { + // The word itself is longer than the available width + // Split the word + let start = 0; + while (start < word.length) { + const part = word.substring(start, start + availableWidth); + lines.push(indent + part); + start += availableWidth; + } + line = ''; + } else { + line = word; + } + } + } + } + // Push the last line if any + if (line.length > 0) { + lines.push(indent + line); + } + }); + + // Join all lines with \n + return lines.join('\n'); +} + export default { + indentText, generateExampleCommand, }; diff --git a/packages/heap-analysis/src/options/HeapAnalysisOutputOption.ts b/packages/heap-analysis/src/options/HeapAnalysisOutputOption.ts index 8a7c1904e..0cd210123 100644 --- a/packages/heap-analysis/src/options/HeapAnalysisOutputOption.ts +++ b/packages/heap-analysis/src/options/HeapAnalysisOutputOption.ts @@ -18,7 +18,13 @@ export default class HeapAnalysisOutputOption extends BaseOption { } getDescription(): string { - return 'specify output format of the analysis (defaults to text)'; + const options = this.getExampleValues() + .map(v => `'${v}'`) + .join(', '); + return ( + 'specify output format of the analysis ' + + `(available options: ${options}; defaults to 'text')` + ); } getExampleValues(): string[] { diff --git a/website/docs/cli/CLI-commands.md b/website/docs/cli/CLI-commands.md index da3371b8c..f75939f6a 100644 --- a/website/docs/cli/CLI-commands.md +++ b/website/docs/cli/CLI-commands.md @@ -215,7 +215,7 @@ memlab analyze collections-with-stale **Options**: * **`--snapshot`**: set file path of the heap snapshot under analysis - * **`--output`**: specify output format of the analysis (defaults to text) + * **`--output`**: specify output format of the analysis (available options: 'text', 'json'; defaults to 'text') * **`--help`**, **`-h`**: print helper text * **`--verbose`**, **`-v`**: show more details * **`--sc`**: set to continuous test mode @@ -232,7 +232,7 @@ memlab analyze detached-DOM **Options**: * **`--snapshot`**: set file path of the heap snapshot under analysis - * **`--output`**: specify output format of the analysis (defaults to text) + * **`--output`**: specify output format of the analysis (available options: 'text', 'json'; defaults to 'text') * **`--help`**, **`-h`**: print helper text * **`--verbose`**, **`-v`**: show more details * **`--sc`**: set to continuous test mode @@ -249,7 +249,7 @@ memlab analyze global-variable **Options**: * **`--snapshot`**: set file path of the heap snapshot under analysis - * **`--output`**: specify output format of the analysis (defaults to text) + * **`--output`**: specify output format of the analysis (available options: 'text', 'json'; defaults to 'text') * **`--help`**, **`-h`**: print helper text * **`--verbose`**, **`-v`**: show more details * **`--sc`**: set to continuous test mode @@ -267,7 +267,7 @@ memlab analyze object **Options**: * **`--snapshot`**: set file path of the heap snapshot under analysis * **`--node-id`**: set heap node ID - * **`--output`**: specify output format of the analysis (defaults to text) + * **`--output`**: specify output format of the analysis (available options: 'text', 'json'; defaults to 'text') * **`--help`**, **`-h`**: print helper text * **`--verbose`**, **`-v`**: show more details * **`--sc`**: set to continuous test mode @@ -284,7 +284,7 @@ memlab analyze object-fanout **Options**: * **`--snapshot`**: set file path of the heap snapshot under analysis - * **`--output`**: specify output format of the analysis (defaults to text) + * **`--output`**: specify output format of the analysis (available options: 'text', 'json'; defaults to 'text') * **`--help`**, **`-h`**: print helper text * **`--verbose`**, **`-v`**: show more details * **`--sc`**: set to continuous test mode @@ -333,7 +333,7 @@ memlab analyze object-size **Options**: * **`--snapshot`**: set file path of the heap snapshot under analysis - * **`--output`**: specify output format of the analysis (defaults to text) + * **`--output`**: specify output format of the analysis (available options: 'text', 'json'; defaults to 'text') * **`--help`**, **`-h`**: print helper text * **`--verbose`**, **`-v`**: show more details * **`--sc`**: set to continuous test mode @@ -414,7 +414,7 @@ memlab analyze unmounted-fiber-node **Options**: * **`--snapshot`**: set file path of the heap snapshot under analysis - * **`--output`**: specify output format of the analysis (defaults to text) + * **`--output`**: specify output format of the analysis (available options: 'text', 'json'; defaults to 'text') * **`--help`**, **`-h`**: print helper text * **`--verbose`**, **`-v`**: show more details * **`--sc`**: set to continuous test mode