|
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