Skip to content

Commit c8b4795

Browse files
committed
Merge branch 'cli-help'
2 parents 2a84f92 + 41e7ea6 commit c8b4795

16 files changed

+800
-145
lines changed

src/Cli/CliApplication.php

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Lkrms\Utility\Catalog\EnvFlag;
1616
use Lkrms\Utility\Arr;
1717
use Lkrms\Utility\Assert;
18+
use Lkrms\Utility\Convert;
1819
use Lkrms\Utility\Json;
1920
use Lkrms\Utility\Package;
2021
use Lkrms\Utility\Pcre;
@@ -236,9 +237,9 @@ private function getHelp(string $name, $node, ?CliHelpStyle $style = null): ?str
236237
foreach ($node as $childName => $childNode) {
237238
$command = $this->getNodeCommand(trim("$name $childName"), $childNode);
238239
if ($command) {
239-
$synopses[] = "__{$childName}__ - " . Formatter::escapeTags($command->description());
240+
$synopses[] = '__' . $childName . '__ - ' . Formatter::escapeTags($command->description());
240241
} elseif (is_array($childNode)) {
241-
$synopses[] = "__{$childName}__";
242+
$synopses[] = '__' . $childName . '__';
242243
}
243244
}
244245

@@ -318,7 +319,7 @@ public function run()
318319
if ($arg === '--version' && !$args) {
319320
$appName = $this->getAppName();
320321
$version = Package::version(true, true);
321-
Console::stdout("__{$appName}__ $version");
322+
Console::stdout('__' . $appName . "__ $version");
322323
return $this;
323324
}
324325

@@ -408,7 +409,7 @@ public function run()
408409
$node &&
409410
($usage = $this->getUsage($name, $node)) !== null
410411
) {
411-
Console::out("\n{$usage}");
412+
Console::out("\n" . $usage);
412413
}
413414
$this->LastExitStatus = 1;
414415
return $this;
@@ -439,9 +440,12 @@ public function runAndExit()
439440
*/
440441
private function generateHelp(string $name, $node, int $target, string ...$args): void
441442
{
443+
$collapseSynopsis = null;
444+
442445
switch ($target) {
443446
case CliHelpTarget::MARKDOWN:
444447
$formats = ConsoleMarkdownFormat::getTagFormats();
448+
$collapseSynopsis = Convert::toBool($args[0] ?? null);
445449
break;
446450

447451
case CliHelpTarget::MAN_PAGE:
@@ -460,9 +464,15 @@ private function generateHelp(string $name, $node, int $target, string ...$args)
460464
throw new LogicException(sprintf('Invalid CliHelpTarget: %d', $target));
461465
}
462466

463-
$formatter = new Formatter($formats);
464-
$usage = $this->getHelp($name, $node, new CliHelpStyle($target));
465-
$usage = $formatter->formatTags($usage, false, null, false);
467+
$formatter = new Formatter($formats, null, fn(): int => 80);
468+
$style = new CliHelpStyle($target, 80, $formatter);
469+
470+
if ($collapseSynopsis !== null) {
471+
$style = $style->withCollapseSynopsis($collapseSynopsis);
472+
}
473+
474+
$usage = $this->getHelp($name, $node, $style);
475+
$usage = $formatter->formatTags($usage);
466476
printf("%s\n", str_replace('\ ', ' ', $usage));
467477
}
468478
}

src/Cli/CliCommand.php

Lines changed: 49 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,9 @@
1111
use Lkrms\Cli\Exception\CliInvalidArgumentsException;
1212
use Lkrms\Cli\Exception\CliUnknownValueException;
1313
use Lkrms\Cli\Support\CliHelpStyle;
14-
use Lkrms\Console\Support\ConsoleLoopbackFormat;
1514
use Lkrms\Console\ConsoleFormatter as Formatter;
1615
use Lkrms\Facade\Console;
1716
use Lkrms\Utility\Arr;
18-
use Lkrms\Utility\Convert;
1917
use Lkrms\Utility\Package;
2018
use Lkrms\Utility\Pcre;
2119
use Lkrms\Utility\Str;
@@ -91,8 +89,6 @@ abstract class CliCommand implements ICliCommand
9189

9290
private int $Runs = 0;
9391

94-
private Formatter $LoopbackFormatter;
95-
9692
/**
9793
* Run the command
9894
*
@@ -297,7 +293,7 @@ final public function getHelp(?CliHelpStyle $style = null): array
297293
$visibility = $style->Visibility;
298294
$width = $style->getWidth();
299295

300-
$formatter = $this->getLoopbackFormatter();
296+
$formatter = $style->Formatter;
301297

302298
$options = [];
303299
foreach ($this->_getOptions() as $option) {
@@ -324,15 +320,17 @@ final public function getHelp(?CliHelpStyle $style = null): array
324320
$line[] = $b . '--' . $long . $b;
325321
}
326322
} else {
327-
if ($option->AllowedValues) {
328-
foreach ($option->AllowedValues as $optionValue) {
323+
if (
324+
$option->AllowedValues ||
325+
$option->ValueType === CliOptionValueType::BOOLEAN
326+
) {
327+
foreach ($option->AllowedValues ?: [true, false] as $optionValue) {
329328
$optionValue = $option->normaliseValueForHelp($optionValue);
330329
$allowed[] = $em . $formatter->escapeTags($optionValue) . $em;
331330
}
332-
} elseif ($option->ValueType === CliOptionValueType::BOOLEAN) {
333-
$allowed[] = $option->normaliseValueForHelp(true);
334-
$allowed[] = $option->normaliseValueForHelp(false);
335-
$booleanValue = true;
331+
if (!$option->AllowedValues) {
332+
$booleanValue = true;
333+
}
336334
}
337335

338336
// `{}` is a placeholder for value name / allowed value list
@@ -394,7 +392,9 @@ final public function getHelp(?CliHelpStyle $style = null): array
394392
);
395393
if (
396394
$booleanValue ||
397-
mb_strlen($formatter->removeTags($indent . $_line)) <= ($width ?: 76)
395+
mb_strlen($formatter->getWrapAfterApply()
396+
? $formatter->formatTags($indent . $_line)
397+
: $formatter->removeTags($indent . $_line)) <= ($width ?: 76)
398398
) {
399399
$allowed = null;
400400
} else {
@@ -410,7 +410,7 @@ final public function getHelp(?CliHelpStyle $style = null): array
410410
$lines = [];
411411
$description = trim((string) $option->Description);
412412
if ($description !== '') {
413-
$lines[] = $this->prepareHelp($description, $formatter, $width, $indent);
413+
$lines[] = $this->prepareHelp($style, $description, $indent);
414414
}
415415

416416
if ($allowed) {
@@ -462,7 +462,7 @@ final public function getHelp(?CliHelpStyle $style = null): array
462462

463463
$description = $this->getLongDescription();
464464
if ((string) $description !== '') {
465-
$description = $this->prepareHelp($description, $formatter, $width);
465+
$description = $this->prepareHelp($style, $description);
466466
}
467467

468468
$help = [
@@ -483,33 +483,22 @@ final public function getHelp(?CliHelpStyle $style = null): array
483483
}
484484
foreach ($sections as $name => $section) {
485485
if ($section !== '') {
486-
$help[$name] = $this->prepareHelp($section, $formatter, $width);
486+
$help[$name] = $this->prepareHelp($style, $section);
487487
}
488488
}
489489

490490
return $help;
491491
}
492492

493-
private function prepareHelp(string $description, Formatter $formatter, ?int $width, ?string $indent = null): string
493+
private function prepareHelp(CliHelpStyle $style, string $text, string $indent = ''): string
494494
{
495-
$description = str_replace(
495+
$text = str_replace(
496496
['{{app}}', '{{program}}', '{{command}}'],
497497
[$this->App->getAppName(), $this->App->getProgramName(), $this->getNameWithProgram()],
498-
$description,
499-
);
500-
501-
$description = $formatter->formatTags(
502-
$description,
503-
true,
504-
$width === null ? null : $width - ($indent ? strlen($indent) : 0),
505-
false
498+
$text,
506499
);
507500

508-
if ($indent) {
509-
return $indent . str_replace("\n", "\n{$indent}", $description);
510-
}
511-
512-
return $description;
501+
return $style->prepareHelp($text, $indent);
513502
}
514503

515504
/**
@@ -519,13 +508,14 @@ final public function getSynopsis(?CliHelpStyle $style = null): string
519508
{
520509
$style ??= new CliHelpStyle();
521510

522-
$hasMarkup = $style->HasMarkup;
523511
$b = $style->Bold;
524512
$prefix = $style->SynopsisPrefix;
525513
$newline = $style->SynopsisNewline;
514+
$softNewline = $style->SynopsisSoftNewline;
526515
$width = $style->getWidth();
527516

528-
$formatter = $this->getLoopbackFormatter();
517+
// Synopsis newlines are hard line breaks, so wrap without markup
518+
$formatter = $style->Formatter->withWrapAfterApply(false);
529519

530520
$name = $b . $this->getNameWithProgram() . $b;
531521
$full = $this->getOptionsSynopsis($style, $collapsed);
@@ -536,23 +526,45 @@ final public function getSynopsis(?CliHelpStyle $style = null): string
536526
$synopsis,
537527
false,
538528
[$width, $width - 4],
539-
!$hasMarkup
529+
true,
540530
);
541531
$wrapped = $prefix . str_replace("\n", $newline, $wrapped, $count);
542532

543533
if (!$style->CollapseSynopsis || !$count) {
534+
if ($softNewline !== '') {
535+
$wrapped = $style->Formatter->formatTags(
536+
$wrapped,
537+
false,
538+
$width,
539+
true,
540+
$softNewline,
541+
);
542+
}
544543
return $wrapped;
545544
}
546545

547546
$synopsis = Arr::implode(' ', [$name, $collapsed]);
548547
}
549548

550-
return $prefix . $formatter->formatTags(
549+
$synopsis = $formatter->formatTags(
551550
$synopsis,
552551
false,
553-
null,
554-
!$hasMarkup
552+
[$width, $width - 4],
553+
true,
555554
);
555+
$synopsis = $prefix . str_replace("\n", $newline, $synopsis);
556+
557+
if ($width !== null && $softNewline !== '') {
558+
$synopsis = $style->Formatter->formatTags(
559+
$synopsis,
560+
false,
561+
$width,
562+
true,
563+
$softNewline,
564+
);
565+
}
566+
567+
return $synopsis;
556568
}
557569

558570
private function getOptionsSynopsis(CliHelpStyle $style, ?string &$collapsed = null): string
@@ -656,7 +668,7 @@ private function getOptionsSynopsis(CliHelpStyle $style, ?string &$collapsed = n
656668
}
657669

658670
$collapsed = Arr::implode(' ', [
659-
$optionalCount > 1 ? $esc . '[<option>]...' : '',
671+
$optionalCount > 1 ? $esc . '[<options>]' : '',
660672
$optionalCount === 1 ? $esc . '[<option>]' : '',
661673
$required ? implode(' ', $required) : '',
662674
$positional ? $esc . '[' . $b . '--' . $b . '] ' . implode(' ', $positional) : '',
@@ -1320,10 +1332,4 @@ private function reset(): void
13201332
$this->HasVersionArgument = false;
13211333
$this->ExitStatus = 0;
13221334
}
1323-
1324-
private function getLoopbackFormatter(): Formatter
1325-
{
1326-
return $this->LoopbackFormatter
1327-
??= new Formatter(ConsoleLoopbackFormat::getTagFormats());
1328-
}
13291335
}

src/Cli/Exception/CliInvalidArgumentsException.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ class CliInvalidArgumentsException extends MultipleErrorException
1212
public function __construct(string ...$errors)
1313
{
1414
parent::__construct('Invalid arguments', ...$errors);
15+
$this->ExitStatus = 1;
1516
}
1617
}

0 commit comments

Comments
 (0)