1616use Inhere \Console \Handler \CommandWrapper ;
1717use Inhere \Console \Util \Helper ;
1818use InvalidArgumentException ;
19+ use Toolkit \Cli \Color \ColorTag ;
1920use Toolkit \Stdlib \Helper \Assert ;
2021use Toolkit \Stdlib \Obj \Traits \NameAliasTrait ;
2122use function array_keys ;
2223use function array_merge ;
2324use function class_exists ;
25+ use function count ;
26+ use function explode ;
27+ use function implode ;
2428use function in_array ;
2529use function is_int ;
2630use function is_object ;
@@ -54,6 +58,13 @@ trait SubCommandsWareTrait
5458 */
5559 protected string $ path = '' ;
5660
61+ /**
62+ * Command full path nodes. eg: ['git', 'remote', 'set-url']
63+ *
64+ * @var string[]
65+ */
66+ protected array $ pathNodes = [];
67+
5768 /**
5869 * The sub-commands of the command
5970 *
@@ -64,6 +75,7 @@ trait SubCommandsWareTrait
6475 * 'config' => [
6576 * 'name' => 'string',
6677 * 'desc' => 'string',
78+ * 'aliases' => [],
6779 * 'options' => [],
6880 * 'arguments' => [],
6981 * ]
@@ -103,11 +115,12 @@ protected function subCommands(): array
103115 protected function dispatchSub (string $ name , array $ args ): mixed
104116 {
105117 $ subInfo = $ this ->commands [$ name ];
106- $ this ->debugf ('dispatch the attached subcommand: %s ' , $ name );
118+ $ this ->debugf ('cmd: %s - dispatch the attached subcommand: %s ' , $ this -> getRealName () , $ name );
107119
108120 // create and init sub-command
109121 $ subCmd = $ this ->createSubCommand ($ subInfo );
110122 $ subCmd ->setParent ($ this );
123+ $ subCmd ->setPath ($ this ->path );
111124 $ subCmd ->setInputOutput ($ this ->input , $ this ->output );
112125
113126 return $ subCmd ->run ($ args );
@@ -273,23 +286,39 @@ public function isSub(string $name): bool
273286 return isset ($ this ->commands [$ name ]);
274287 }
275288
289+ /**
290+ * @param string $sep
291+ *
292+ * @return string
293+ */
294+ public function getPath (string $ sep = '' ): string
295+ {
296+ return $ sep ? implode ($ sep , $ this ->pathNodes ) : $ this ->path ;
297+ }
298+
276299 /**
277300 * @param string $path
278301 */
279302 public function setPath (string $ path ): void
280303 {
281304 $ this ->path = $ path ;
305+ // set path nodes
306+ $ this ->pathNodes = explode (' ' , $ path );
282307 }
283308
284309 /**
285310 * @param string $name
286311 */
287- public function addPath (string $ name ): void
312+ public function addPathNode (string $ name ): void
288313 {
289314 if ($ this ->path ) {
290315 $ this ->path .= ' ' . $ name ;
316+ // add path nodes
317+ $ this ->pathNodes [] = $ name ;
291318 } else {
292319 $ this ->path = $ name ;
320+ // set path nodes
321+ $ this ->pathNodes = [$ name ];
293322 }
294323 }
295324
@@ -339,6 +368,14 @@ public function setBlocked(array $blocked): void
339368 $ this ->blocked = $ blocked ;
340369 }
341370
371+ /**
372+ * @return bool
373+ */
374+ public function hasSubs (): bool
375+ {
376+ return count ($ this ->commands ) > 0 ;
377+ }
378+
342379 /**
343380 * @return array
344381 */
@@ -364,15 +401,24 @@ public function getSubsForHelp(): array
364401 foreach ($ this ->commands as $ name => $ subInfo ) {
365402 $ sub = $ subInfo ['handler ' ];
366403 if ($ sub instanceof Command) {
367- $ subs [$ name ] = $ sub ->getRealDesc ();
404+ $ desc = $ sub ->getRealDesc ();
405+ // alias names
406+ $ aliases = $ sub ::aliases ();
368407 } elseif (is_string ($ sub )) {
369408 /** @var Command $sub */
370- $ subs [$ name ] = $ sub ::getDesc ();
409+ $ desc = $ sub ::getDesc ();
410+ // alias names
411+ $ aliases = $ sub ::aliases ();
371412 } else {
372- $ subConf = $ subInfo ['config ' ];
373-
374- $ subs [$ name ] = $ subConf ['desc ' ] ?? 'no description ' ;
413+ $ conf = $ subInfo ['config ' ];
414+ $ desc = $ conf ['desc ' ] ?? 'no description ' ;
415+ // alias names
416+ $ aliases = $ conf ['aliases ' ] ?? [];
375417 }
418+
419+ $ extra = $ aliases ? ColorTag::wrap (' (alias: ' . implode (', ' , $ aliases ) . ') ' , 'info ' ) : '' ;
420+ // add help desc
421+ $ subs [$ name ] = $ desc . $ extra ;
376422 }
377423
378424 return $ subs ;
0 commit comments