From 43e04954b413805ed7d5a9b8fcef01d719ec790c Mon Sep 17 00:00:00 2001 From: Inhere Date: Sun, 26 Dec 2021 22:54:16 +0800 Subject: [PATCH] feat: support render attached subcommand help --- examples/Command/TestCommand.php | 7 +++-- src/Decorate/CommandHelpTrait.php | 11 ++++++-- src/Decorate/ControllerHelpTrait.php | 4 +++ src/Decorate/SubCommandsWareTrait.php | 40 +++++++++++++++++++++++---- 4 files changed, 53 insertions(+), 9 deletions(-) diff --git a/examples/Command/TestCommand.php b/examples/Command/TestCommand.php index 6239cb7..a51157e 100644 --- a/examples/Command/TestCommand.php +++ b/examples/Command/TestCommand.php @@ -10,6 +10,7 @@ namespace Inhere\Console\Examples\Command; use Inhere\Console\Command; +use Inhere\Console\Handler\CommandWrapper; use Inhere\Console\IO\Input; use Inhere\Console\IO\Output; @@ -26,9 +27,11 @@ class TestCommand extends Command protected function subCommands(): array { return [ - 'sub' => static function ($fs, $out): void { + 'sub' => CommandWrapper::new(static function ($fs, $out): void { $out->println('hello, this is an sub command of test.'); - }, + }, [ + 'desc' => 'sub command of test command' + ]), ]; } diff --git a/src/Decorate/CommandHelpTrait.php b/src/Decorate/CommandHelpTrait.php index f73fd86..79e53f9 100644 --- a/src/Decorate/CommandHelpTrait.php +++ b/src/Decorate/CommandHelpTrait.php @@ -14,6 +14,7 @@ use Toolkit\PFlag\FlagsParser; use Toolkit\PFlag\FlagUtil; use function implode; +use function ksort; use function sprintf; use function strtr; use function ucfirst; @@ -81,7 +82,7 @@ protected function addCommentsVars(array $map): void */ protected function setCommentsVar(string $name, array|string $value): void { - $this->commentsVars[$name] = is_array($value) ? implode(',', $value) : (string)$value; + $this->commentsVars[$name] = is_array($value) ? implode(',', $value) : $value; } /** @@ -148,8 +149,14 @@ public function showHelpByFlagsParser(FlagsParser $fs, array $aliases = [], stri $help['Options:'] = FlagUtil::alignOptions($fs->getOptsHelpLines()); $help['Argument:'] = $fs->getArgsHelpLines(); - $help['Example:'] = $fs->getExampleHelp(); + if ($subCmds = $this->getSubsForHelp()) { + // sort commands + ksort($subCmds); + $help['Commands:'] = $subCmds; + } + + $help['Example:'] = $fs->getExampleHelp(); $help['More Help:'] = $fs->getMoreHelp(); // no group options. only set key position. diff --git a/src/Decorate/ControllerHelpTrait.php b/src/Decorate/ControllerHelpTrait.php index af6c87c..7fb0553 100644 --- a/src/Decorate/ControllerHelpTrait.php +++ b/src/Decorate/ControllerHelpTrait.php @@ -139,6 +139,10 @@ public function showCommandList(): void $commands[$cmd] = $desc; } + if ($subCmds = $this->getSubsForHelp()) { + $commands = array_merge($commands, $subCmds); + } + // sort commands ksort($commands); diff --git a/src/Decorate/SubCommandsWareTrait.php b/src/Decorate/SubCommandsWareTrait.php index b042c70..ce4655e 100644 --- a/src/Decorate/SubCommandsWareTrait.php +++ b/src/Decorate/SubCommandsWareTrait.php @@ -132,10 +132,10 @@ protected function createSubCommand(array $subInfo): Command * Register a app independent console command * * @param string|class-string $name - * @param string|Closure|CommandInterface|null $handler + * @param class-string|CommandInterface|null $handler * @param array $config */ - public function addSub(string $name, string|Closure|CommandInterface $handler = null, array $config = []): void + public function addSub(string $name, string|CommandInterface $handler = null, array $config = []): void { if (!$handler && class_exists($name)) { /** @var Command $name name is an command class */ @@ -171,9 +171,9 @@ public function addSub(string $name, string|Closure|CommandInterface $handler = if ($aliases = $handler::aliases()) { $config['aliases'] = array_merge($config['aliases'], $aliases); } - } elseif (!is_object($handler) || !ConsoleUtil::isValidCmdObject($handler)) { + } elseif (!is_object($handler) || !$handler instanceof Command) { Helper::throwInvalidArgument( - 'The command handler must is an subclass of %s OR a Closure OR a sub-object of %s', + 'The subcommand handler must be an subclass of %s OR a sub-object of %s', Command::class, Command::class, ); @@ -317,8 +317,38 @@ public function setBlocked(array $blocked): void /** * @return array */ - public function getCommandNames(): array + public function getSubNames(): array { return array_keys($this->commands); } + + /** + * @return array + */ + public function getCommands(): array + { + return $this->commands; + } + + /** + * @return array + */ + public function getSubsForHelp(): array + { + $subs = []; + foreach ($this->commands as $name => $subInfo) { + $sub = $subInfo['handler']; + if ($sub instanceof Command) { + $subs[$name] = $sub->getRealDesc(); + } elseif (is_string($sub)) { + $subs[$name] = $sub::getDesc(); + } else { + $subConf = $subInfo['config']; + + $subs[$name] = $subConf['desc'] ?? 'no description'; + } + } + + return $subs; + } }