|
3 | 3 | namespace Toolkit\PFlag; |
4 | 4 |
|
5 | 5 | use Toolkit\Cli\Cli; |
6 | | -use Toolkit\Cli\Color\ColorTag; |
7 | 6 | use Toolkit\Cli\Helper\FlagHelper; |
| 7 | +use Toolkit\PFlag\Concern\HelperRenderTrait; |
8 | 8 | use Toolkit\PFlag\Concern\RuleParserTrait; |
9 | 9 | use Toolkit\PFlag\Contract\ParserInterface; |
10 | | -use Toolkit\PFlag\Contract\ValidatorInterface; |
11 | | -use Toolkit\PFlag\Flag\Argument; |
12 | | -use Toolkit\PFlag\Flag\Option; |
13 | | -use Toolkit\Stdlib\Helper\DataHelper; |
14 | | -use Toolkit\Stdlib\Helper\IntHelper; |
15 | 10 | use Toolkit\Stdlib\Obj; |
16 | 11 | use Toolkit\Stdlib\Obj\Traits\NameAliasTrait; |
17 | 12 | use Toolkit\Stdlib\Obj\Traits\QuickInitTrait; |
18 | | -use Toolkit\Stdlib\Str; |
19 | 13 | use function array_merge; |
20 | 14 | use function array_shift; |
21 | 15 | use function array_values; |
22 | 16 | use function basename; |
23 | | -use function count; |
24 | 17 | use function explode; |
25 | | -use function is_object; |
26 | | -use function ksort; |
27 | | -use function method_exists; |
28 | | -use function sprintf; |
29 | | -use function strlen; |
30 | 18 | use function strpos; |
31 | | -use function trim; |
32 | 19 |
|
33 | 20 | /** |
34 | 21 | * class AbstractFlags |
35 | 22 | * abstract parser |
36 | 23 | */ |
37 | 24 | abstract class AbstractFlags implements ParserInterface |
38 | 25 | { |
| 26 | + use HelperRenderTrait; |
39 | 27 | use QuickInitTrait; |
40 | 28 | use NameAliasTrait; |
41 | 29 | use RuleParserTrait; |
@@ -142,6 +130,9 @@ abstract class AbstractFlags implements ParserInterface |
142 | 130 | 'argNameLen' => 12, |
143 | 131 | 'optNameLen' => 12, |
144 | 132 | 'descNlOnOptLen' => self::OPT_MAX_WIDTH, |
| 133 | + // more settings |
| 134 | + 'exampleHelp' => '', |
| 135 | + 'moreHelp' => '', |
145 | 136 | ]; |
146 | 137 |
|
147 | 138 | /** |
@@ -208,29 +199,6 @@ abstract class AbstractFlags implements ParserInterface |
208 | 199 | */ |
209 | 200 | protected $strictCheckArgs = false; |
210 | 201 |
|
211 | | - // -------------------- settings for render help -------------------- |
212 | | - |
213 | | - /** |
214 | | - * Auto render help on provide '-h', '--help' |
215 | | - * |
216 | | - * @var bool |
217 | | - */ |
218 | | - protected $autoRenderHelp = true; |
219 | | - |
220 | | - /** |
221 | | - * Show flag data type on render help |
222 | | - * |
223 | | - * @var bool |
224 | | - */ |
225 | | - protected $showTypeOnHelp = true; |
226 | | - |
227 | | - /** |
228 | | - * Custom help renderer. |
229 | | - * |
230 | | - * @var callable |
231 | | - */ |
232 | | - protected $helpRenderer; |
233 | | - |
234 | 202 | /** |
235 | 203 | * Class constructor. |
236 | 204 | * |
@@ -342,244 +310,10 @@ public function __toString(): string |
342 | 310 | */ |
343 | 311 | abstract public function buildHelp(bool $withColor = true): string; |
344 | 312 |
|
345 | | - /** |
346 | | - * @param array $argDefines |
347 | | - * @param array $optDefines |
348 | | - * @param bool $withColor |
349 | | - * |
350 | | - * @return string |
351 | | - */ |
352 | | - protected function doBuildHelp(array $argDefines, array $optDefines, bool $withColor): string |
353 | | - { |
354 | | - $buf = Str\StrBuffer::new(); |
355 | | - |
356 | | - // ------- desc ------- |
357 | | - if ($title = $this->desc) { |
358 | | - $buf->writeln(Str::ucfirst($title) . "\n"); |
359 | | - } |
360 | | - |
361 | | - $hasArgs = count($argDefines) > 0; |
362 | | - $hasOpts = count($optDefines) > 0; |
363 | | - |
364 | | - // ------- usage ------- |
365 | | - $binName = $this->scriptName ?: FlagUtil::getBinName(); |
366 | | - if ($hasArgs || $hasOpts) { |
367 | | - $buf->writeln("<ylw>Usage:</ylw> $binName [Options ...] -- [Arguments ...]\n"); |
368 | | - } |
369 | | - |
370 | | - // ------- args ------- |
371 | | - $nameTag = 'info'; |
372 | | - $fmtArgs = $this->buildArgsForHelp($argDefines); |
373 | | - |
374 | | - if ($hasArgs) { |
375 | | - $buf->writeln('<ylw>Arguments:</ylw>'); |
376 | | - } |
377 | | - |
378 | | - $nameLen = $this->settings['argNameLen']; |
379 | | - foreach ($fmtArgs as $hName => $arg) { |
380 | | - [$desc, $lines] = $this->formatDesc($arg); |
381 | | - |
382 | | - // write to buffer. |
383 | | - $hName = Str::padRight($hName, $nameLen); |
384 | | - $buf->writef(" <%s>%s</%s> %s\n", $nameTag, $hName, $nameTag, $desc); |
385 | | - |
386 | | - // remaining desc lines |
387 | | - if ($lines) { |
388 | | - $indent = Str::repeat(' ', $nameLen); |
389 | | - foreach ($lines as $line) { |
390 | | - $buf->writef(" %s%s\n", $indent, $line); |
391 | | - } |
392 | | - } |
393 | | - } |
394 | | - |
395 | | - $hasArgs && $buf->writeln(''); |
396 | | - |
397 | | - // ------- opts ------- |
398 | | - if ($hasOpts) { |
399 | | - $buf->writeln('<ylw>Options:</ylw>'); |
400 | | - } |
401 | | - |
402 | | - $nameTag = 'info'; |
403 | | - $fmtOpts = $this->buildOptsForHelp($optDefines); |
404 | | - |
405 | | - $nameLen = $this->settings['optNameLen']; |
406 | | - $maxWidth = $this->settings['descNlOnOptLen']; |
407 | | - foreach ($fmtOpts as $hName => $opt) { |
408 | | - [$desc, $lines] = $this->formatDesc($opt); |
409 | | - |
410 | | - // need echo desc at newline. |
411 | | - $hName = Str::padRight($hName, $nameLen); |
412 | | - if (strlen($hName) > $maxWidth) { |
413 | | - $buf->writef(" <%s>%s</%s>\n", $nameTag, $hName, $nameTag); |
414 | | - $buf->writef(" %s%s\n", Str::repeat(' ', $nameLen), $desc); |
415 | | - } else { |
416 | | - $buf->writef(" <%s>%s</%s> %s\n", $nameTag, $hName, $nameTag, $desc); |
417 | | - } |
418 | | - |
419 | | - // remaining desc lines |
420 | | - if ($lines) { |
421 | | - $indent = Str::repeat(' ', $nameLen); |
422 | | - foreach ($lines as $line) { |
423 | | - $buf->writef(" %s%s\n", $indent, $line); |
424 | | - } |
425 | | - } |
426 | | - } |
427 | | - |
428 | | - return $withColor ? $buf->clear() : ColorTag::clear($buf->clear()); |
429 | | - } |
430 | | - |
431 | | - /** |
432 | | - * @param array|Option|Argument $define |
433 | | - * |
434 | | - * @return array |
435 | | - * @see DEFINE_ITEM for array $define |
436 | | - */ |
437 | | - protected function formatDesc($define): array |
438 | | - { |
439 | | - $desc = $define['desc']; |
440 | | - |
441 | | - if ($define['required']) { |
442 | | - $desc = '<red1>*</red1>' . $desc; |
443 | | - } |
444 | | - |
445 | | - // validator limit |
446 | | - if (!empty($define['validator'])) { |
447 | | - $v = $define['validator']; |
448 | | - |
449 | | - /** @see ValidatorInterface */ |
450 | | - if (is_object($v) && method_exists($v, '__toString')) { |
451 | | - $limit = (string)$v; |
452 | | - $desc .= $limit ? ' ' . $limit : ''; |
453 | | - } |
454 | | - } |
455 | | - |
456 | | - // default value. |
457 | | - if (isset($define['default']) && $define['default'] !== null) { |
458 | | - $desc .= sprintf('(default <mga>%s</mga>)', DataHelper::toString($define['default'])); |
459 | | - } |
460 | | - |
461 | | - // desc has multi line |
462 | | - $lines = []; |
463 | | - if (strpos($desc, "\n") > 0) { |
464 | | - $lines = explode("\n", $desc); |
465 | | - $desc = array_shift($lines); |
466 | | - } |
467 | | - |
468 | | - return [$desc, $lines]; |
469 | | - } |
470 | | - |
471 | | - /** |
472 | | - * @param array $argDefines |
473 | | - * |
474 | | - * @return array |
475 | | - */ |
476 | | - protected function buildArgsForHelp(array $argDefines): array |
477 | | - { |
478 | | - $fmtArgs = []; |
479 | | - $maxLen = $this->settings['argNameLen']; |
480 | | - |
481 | | - /** @var array|Argument $arg {@see DEFINE_ITEM} */ |
482 | | - foreach ($argDefines as $arg) { |
483 | | - $helpName = $arg['name'] ?: 'arg' . $arg['index']; |
484 | | - if ($desc = $arg['desc']) { |
485 | | - $desc = trim($desc); |
486 | | - } |
487 | | - |
488 | | - // ensure desc is not empty |
489 | | - $arg['desc'] = $desc ? Str::ucfirst($desc) : "Argument $helpName"; |
490 | | - |
491 | | - $type = $arg['type']; |
492 | | - if (FlagType::isArray($type)) { |
493 | | - $helpName .= '...'; |
494 | | - } |
495 | | - |
496 | | - if ($this->showTypeOnHelp) { |
497 | | - $typeName = FlagType::getHelpName($type); |
498 | | - $helpName .= $typeName ? " $typeName" : ''; |
499 | | - } |
500 | | - |
501 | | - $maxLen = IntHelper::getMax($maxLen, strlen($helpName)); |
502 | | - |
503 | | - // append |
504 | | - $fmtArgs[$helpName] = $arg; |
505 | | - } |
506 | | - |
507 | | - $this->settings['argNameLen'] = $maxLen; |
508 | | - return $fmtArgs; |
509 | | - } |
510 | | - |
511 | | - /** |
512 | | - * @param array $optDefines |
513 | | - * |
514 | | - * @return array |
515 | | - */ |
516 | | - protected function buildOptsForHelp(array $optDefines): array |
517 | | - { |
518 | | - if (!$optDefines) { |
519 | | - return []; |
520 | | - } |
521 | | - |
522 | | - $fmtOpts = []; |
523 | | - $nameLen = $this->settings['optNameLen']; |
524 | | - ksort($optDefines); |
525 | | - |
526 | | - /** @var array|Option $opt {@see DEFINE_ITEM} */ |
527 | | - foreach ($optDefines as $name => $opt) { |
528 | | - $names = $opt['shorts']; |
529 | | - /** @see Option support alias name. */ |
530 | | - if (isset($opt['alias']) && $opt['alias']) { |
531 | | - $names[] = $opt['alias']; |
532 | | - } |
533 | | - // real name. |
534 | | - $names[] = $name; |
535 | | - |
536 | | - if ($desc = $opt['desc']) { |
537 | | - $desc = trim($desc); |
538 | | - } |
539 | | - |
540 | | - // ensure desc is not empty |
541 | | - $opt['desc'] = $desc ? Str::ucfirst($desc) : "Option $name"; |
542 | | - |
543 | | - $helpName = FlagUtil::buildOptHelpName($names); |
544 | | - if ($this->showTypeOnHelp) { |
545 | | - $typeName = FlagType::getHelpName($opt['type']); |
546 | | - $helpName .= $typeName ? " $typeName" : ''; |
547 | | - } |
548 | | - |
549 | | - $nameLen = IntHelper::getMax($nameLen, strlen($helpName)); |
550 | | - // append |
551 | | - $fmtOpts[$helpName] = $opt; |
552 | | - } |
553 | | - |
554 | | - // limit option name width |
555 | | - $maxLen = IntHelper::getMax($this->settings['descNlOnOptLen'], self::OPT_MAX_WIDTH); |
556 | | - |
557 | | - $this->settings['descNlOnOptLen'] = $maxLen; |
558 | | - // set opt name len |
559 | | - $this->settings['optNameLen'] = IntHelper::getMin($nameLen, $maxLen); |
560 | | - return $fmtOpts; |
561 | | - } |
562 | | - |
563 | 313 | /**************************************************************** |
564 | 314 | * getter/setter methods |
565 | 315 | ***************************************************************/ |
566 | 316 |
|
567 | | - /** |
568 | | - * @return callable |
569 | | - */ |
570 | | - public function getHelpRenderer(): callable |
571 | | - { |
572 | | - return $this->helpRenderer; |
573 | | - } |
574 | | - |
575 | | - /** |
576 | | - * @param callable $helpRenderer |
577 | | - */ |
578 | | - public function setHelpRenderer(callable $helpRenderer): void |
579 | | - { |
580 | | - $this->helpRenderer = $helpRenderer; |
581 | | - } |
582 | | - |
583 | 317 | /** |
584 | 318 | * @return array |
585 | 319 | */ |
@@ -790,36 +524,4 @@ public function setScriptName(string $scriptName): void |
790 | 524 | { |
791 | 525 | $this->scriptName = $scriptName; |
792 | 526 | } |
793 | | - |
794 | | - /** |
795 | | - * @return bool |
796 | | - */ |
797 | | - public function isAutoRenderHelp(): bool |
798 | | - { |
799 | | - return $this->autoRenderHelp; |
800 | | - } |
801 | | - |
802 | | - /** |
803 | | - * @param bool $autoRenderHelp |
804 | | - */ |
805 | | - public function setAutoRenderHelp(bool $autoRenderHelp): void |
806 | | - { |
807 | | - $this->autoRenderHelp = $autoRenderHelp; |
808 | | - } |
809 | | - |
810 | | - /** |
811 | | - * @return bool |
812 | | - */ |
813 | | - public function isShowTypeOnHelp(): bool |
814 | | - { |
815 | | - return $this->showTypeOnHelp; |
816 | | - } |
817 | | - |
818 | | - /** |
819 | | - * @param bool $showTypeOnHelp |
820 | | - */ |
821 | | - public function setShowTypeOnHelp(bool $showTypeOnHelp): void |
822 | | - { |
823 | | - $this->showTypeOnHelp = $showTypeOnHelp; |
824 | | - } |
825 | 527 | } |
0 commit comments