@@ -193,11 +193,11 @@ protected function onNotFound(string $action): bool
193193 }
194194
195195 /**
196- * @param string $command command in the group
196+ * @param string $command
197197 *
198- * @return int|mixed
198+ * @return string
199199 */
200- public function run (string $ command = '' )
200+ protected function findCommandName (string $ command): string
201201 {
202202 if (!$ command = trim ($ command , $ this ->delimiter )) {
203203 $ command = $ this ->defaultAction ;
@@ -214,6 +214,19 @@ public function run(string $command = '')
214214 }
215215 }
216216
217+ return $ command ;
218+ }
219+
220+ /**
221+ * @param string $command command in the group
222+ *
223+ * @return int|mixed
224+ * @throws ReflectionException
225+ */
226+ public function run (string $ command = '' )
227+ {
228+ $ command = $ this ->findCommandName ($ command );
229+
217230 // if not input sub-command, render group help.
218231 if (!$ command ) {
219232 $ this ->debugf ('sub-command is empty, display help for the group: %s ' , self ::getName ());
@@ -226,13 +239,27 @@ public function run(string $command = '')
226239 $ command = $ this ->getRealCommandName ($ command );
227240
228241 // convert 'boo-foo' to 'booFoo'
229- $ this ->action = Str::camelCase ($ command );
230- $ this ->debugf ('will run the group action: %s, sub-command: %s ' , $ this ->action , $ command );
242+ $ this ->action = $ action = Str::camelCase ($ command );
243+ $ this ->debugf ("will run the '%s' group action: %s, sub-command: %s " , static ::getName (), $ this ->action , $ command );
244+
245+ $ this ->beforeRun ();
246+
247+ // check method not exist
248+ $ method = $ this ->getMethodName ($ action );
249+
250+ // if command method not exists.
251+ if (!method_exists ($ this , $ method )) {
252+ return $ this ->handleNotFound (static ::getName (), $ action );
253+ }
231254
232255 // do running
233256 return parent ::run ($ command );
234257 }
235258
259+ protected function beforeRun (): void
260+ {
261+ }
262+
236263 /**
237264 * Load command configure
238265 */
@@ -288,7 +315,6 @@ protected function afterAction(): void
288315 * @param Output $output
289316 *
290317 * @return mixed
291- * @throws ReflectionException
292318 */
293319 final public function execute ($ input , $ output )
294320 {
@@ -301,40 +327,47 @@ final public function execute($input, $output)
301327 return -1 ;
302328 }
303329
304- $ method = $ this ->actionSuffix ? $ action . ucfirst ( $ this -> actionSuffix ) : $ action ;
330+ $ method = $ this ->getMethodName ( $ action) ;
305331
306332 // the action method exists and only allow access public method.
307- // if (method_exists($this, $method) && (($rfm = new ReflectionMethod($this, $method)) && $rfm->isPublic())) {
308- if (method_exists ($ this , $ method )) {
309- // before run action
310- if (!$ this ->beforeAction ()) {
311- $ this ->debugf ('beforeAction() returns FALSE, interrupt processing continues ' );
312- return 0 ;
313- }
333+ // if (method_exists($this, $method)) {
334+ // before run action
335+ if (!$ this ->beforeAction ()) {
336+ $ this ->debugf ('beforeAction() returns FALSE, interrupt processing continues ' );
337+ return 0 ;
338+ }
314339
315- if (method_exists ($ this , $ beforeFunc = 'before ' . ucfirst ($ action ))) {
316- $ beforeOk = $ this ->$ beforeFunc ($ input , $ output );
317- if ($ beforeOk === false ) {
318- $ this ->debugf ('%s() returns FALSE, interrupt processing continues ' , $ beforeFunc );
319- return 0 ;
320- }
340+ if (method_exists ($ this , $ beforeFunc = 'before ' . ucfirst ($ action ))) {
341+ $ beforeOk = $ this ->$ beforeFunc ($ input , $ output );
342+ if ($ beforeOk === false ) {
343+ $ this ->debugf ('%s() returns FALSE, interrupt processing continues ' , $ beforeFunc );
344+ return 0 ;
321345 }
346+ }
322347
323- // run action
324- $ result = $ this ->$ method ($ input , $ output );
325-
326- // after run action
327- if (method_exists ($ this , $ after = 'after ' . ucfirst ($ action ))) {
328- $ this ->$ after ($ input , $ output );
329- }
348+ // run action
349+ $ result = $ this ->$ method ($ input , $ output );
330350
331- $ this ->afterAction ();
332- return $ result ;
351+ // after run action
352+ if (method_exists ($ this , $ after = 'after ' . ucfirst ($ action ))) {
353+ $ this ->$ after ($ input , $ output );
333354 }
334355
356+ $ this ->afterAction ();
357+ return $ result ;
358+ }
359+
360+ /**
361+ * @param string $group
362+ * @param string $action
363+ *
364+ * @return int
365+ */
366+ protected function handleNotFound (string $ group , string $ action ): int
367+ {
335368 // if user custom handle not found logic.
336369 if ($ this ->onNotFound ($ action )) {
337- $ this ->debugf ('user custom handle the action "%s" not found logic ' , $ action );
370+ $ this ->debugf ('user custom handle the "%s" action "%s" not found ' , $ group , $ action );
338371 return 0 ;
339372 }
340373
@@ -344,22 +377,33 @@ final public function execute($input, $output)
344377 // if (($notFoundCallback = $this->notFoundCallback) && method_exists($this, $notFoundCallback)) {
345378 // $result = $this->{$notFoundCallback}($action);
346379 // } else {
347- $ output ->liteError ("Sorry, The command ' $ action' not exist of the group ' { $ group} '! " );
380+ $ this -> output ->liteError ("Sorry, The command ' $ action' not exist of the group ' $ group'! " );
348381
349382 // find similar command names
350383 $ similar = Helper::findSimilar ($ action , $ this ->getAllCommandMethods (null , true ));
351384
352385 if ($ similar ) {
353- $ output ->write ( sprintf ( "\nMaybe what you mean is: \n <info>%s</info> " , implode (', ' , $ similar) ));
386+ $ this -> output ->writef ( "\nMaybe what you mean is: \n <info>%s</info> " , implode (', ' , $ similar ));
354387 } else {
355388 $ this ->showCommandList ();
356389 }
357390
358391 return -1 ;
359392 }
360393
394+ /**
395+ * @param string $action
396+ *
397+ * @return string
398+ */
399+ protected function getMethodName (string $ action ): string
400+ {
401+ return $ this ->actionSuffix ? $ action . ucfirst ($ this ->actionSuffix ) : $ action ;
402+ }
403+
361404 /**
362405 * @return bool
406+ * @throws ReflectionException
363407 */
364408 protected function showHelp (): bool
365409 {
@@ -402,13 +446,13 @@ public function getGroupOptions(): array
402446 * -s, --search Search command by input keywords
403447 * --format Set the help information dump format(raw, xml, json, markdown)
404448 * @return int
449+ * @throws ReflectionException
405450 * @example
406451 * {script} {name} -h
407452 * {script} {name}:help
408453 * {script} {name}:help index
409454 * {script} {name}:index -h
410455 * {script} {name} index
411- *
412456 */
413457 final public function helpCommand (): int
414458 {
@@ -519,8 +563,8 @@ final public function showCommandList(): void
519563 $ name = $ sName . $ this ->delimiter ;
520564 // $usage = "$script {$name}<info>{command}</info> [--options ...] [arguments ...]";
521565 $ usage = [
522- "$ script { $ name} <info>{command}</info> [--options ...] [arguments ...] " ,
523- "$ script { $ sName} <info>{command}</info> [--options ...] [arguments ...] " ,
566+ "$ script $ name<info>{command}</info> [--options ...] [arguments ...] " ,
567+ "$ script $ sName <info>{command}</info> [--options ...] [arguments ...] " ,
524568 ];
525569 }
526570
@@ -709,18 +753,17 @@ public function setActionSuffix(string $actionSuffix): void
709753
710754 /**
711755 * @return bool
756+ * @deprecated
712757 */
713758 public function isExecutionAlone (): bool
714759 {
715760 throw new RuntimeException ('please call isAttached() instead ' );
716761 }
717762
718763 /**
719- * @param bool $executionAlone
720- *
721764 * @deprecated
722765 */
723- public function setExecutionAlone ($ executionAlone = true ): void
766+ public function setExecutionAlone (): void
724767 {
725768 throw new RuntimeException ('please call setAttached() instead ' );
726769 }
0 commit comments