From 0ac2c38873bc75b34b7beaf888e94e14b5972365 Mon Sep 17 00:00:00 2001 From: SonyPradana Date: Fri, 3 Nov 2023 22:21:34 +0700 Subject: [PATCH] fix: `HelpCommand` parse new commandmap --- src/System/Integrate/Console/HelpCommand.php | 93 ++++++++++++------- .../Integrate/ValueObjects/CommandMap.php | 8 ++ tests/Integrate/Commands/HelpCommandsTest.php | 90 ++++++++++++++++++ 3 files changed, 159 insertions(+), 32 deletions(-) diff --git a/src/System/Integrate/Console/HelpCommand.php b/src/System/Integrate/Console/HelpCommand.php index e5a91933..5179d0fc 100644 --- a/src/System/Integrate/Console/HelpCommand.php +++ b/src/System/Integrate/Console/HelpCommand.php @@ -7,6 +7,7 @@ use System\Console\Command; use System\Console\Style\Style; use System\Console\Traits\PrintHelpTrait; +use System\Integrate\ValueObjects\CommandMap; use System\Text\Str; use function System\Console\info; @@ -83,38 +84,38 @@ public function main(): int { $has_visited = []; $this->print_help = [ - 'margin-left' => 8, - 'column-1-min-lenght' => 16, + 'margin-left' => 8, + 'column-1-min-lenght' => 16, ]; - foreach ($this->commands as $command) { - if (!in_array($command['class'], $has_visited)) { - $class_name = $command['class']; - $has_visited[] = $class_name; + foreach ($this->commandMaps() as $command) { + $class = $command->class(); + if (!in_array($class, $has_visited)) { + $has_visited[] = $class; - if (class_exists($class_name)) { - $class = new $class_name([]); + if (class_exists($class)) { + $class = new $class([], $command->defaultOption()); if (!method_exists($class, 'printHelp')) { continue; } - $res = app()->call([$class, 'printHelp']) ?? []; + $help = app()->call([$class, 'printHelp']) ?? []; - if (isset($res['commands']) && $res['commands'] != null) { - foreach ($res['commands'] as $command => $desc) { + if (isset($help['commands']) && $help['commands'] !== null) { + foreach ($help['commands'] as $command => $desc) { $this->command_describes[$command] = $desc; } } - if (isset($res['options']) && $res['options'] != null) { - foreach ($res['options'] as $option => $desc) { + if (isset($help['options']) && $help['options'] !== null) { + foreach ($help['options'] as $option => $desc) { $this->option_describes[$option] = $desc; } } - if (isset($res['relation']) && $res['relation'] != null) { - foreach ($res['relation'] as $option => $desc) { + if (isset($help['relation']) && $help['relation'] != null) { + foreach ($help['relation'] as $option => $desc) { $this->command_relation[$option] = $desc; } } @@ -163,18 +164,31 @@ public function commandList(): int { style('List of all command registered:')->out(); - foreach ($this->commands as $command) { - // get command - if (is_array($command['cmd'])) { - style(implode(', ', $command['cmd']))->textBlue()->out(); - } else { - style($command['cmd'])->textBlue()->out(); + $maks1 = 0; + $maks2 = 0; + foreach ($this->commandMaps() as $command) { + $lenght = Str::length(implode(', ', $command->patterns())); + if ($lenght > $maks1) { + $maks1 = $lenght; + } + + $lenght = Str::length($command->class()); + if ($lenght > $maks2) { + $maks2 = $lenght; } + } + + foreach ($this->commandMaps() as $command) { + style(implode(', ', $command->patterns()))->textLightYellow()->out(false); - style("\t") - ->push($command['class'])->textGreen() - ->push("\t")->push($command['fn'])->textDim() - ->out(); + $lenght1 = Str::length(implode(', ', $command->patterns())); + $lenght2 = Str::length($command->class()); + style('') + ->repeat(' ', $maks1 - $lenght1 + 4) + ->push($command->class())->textGreen() + ->repeat('.', $maks2 - $lenght2 + 8)->textDim() + ->push($command->method()) + ->out(); } return 0; @@ -216,18 +230,18 @@ public function commandHelp(): int if (class_exists($class_name)) { $class = new $class_name([]); - $res = app()->call([$class, 'printHelp']) ?? []; + $help = app()->call([$class, 'printHelp']) ?? []; - if (isset($res['commands']) && $res['commands'] != null) { - $this->command_describes = $res['commands']; + if (isset($help['commands']) && $help['commands'] != null) { + $this->command_describes = $help['commands']; } - if (isset($res['options']) && $res['options'] != null) { - $this->option_describes = $res['options']; + if (isset($help['options']) && $help['options'] != null) { + $this->option_describes = $help['options']; } - if (isset($res['relation']) && $res['relation'] != null) { - $this->command_relation = $res['relation']; + if (isset($help['relation']) && $help['relation'] != null) { + $this->command_relation = $help['relation']; } style('Avilabe command:')->newLines()->out(); @@ -244,4 +258,19 @@ public function commandHelp(): int return 1; } + + /** + * Transform commandsmap array to CommandMap. + * + * @return CommandMap[] + */ + private function commandMaps() + { + $commandmap = []; + foreach ($this->commands as $command) { + $commandmap[] = new CommandMap($command); + } + + return $commandmap; + } } diff --git a/src/System/Integrate/ValueObjects/CommandMap.php b/src/System/Integrate/ValueObjects/CommandMap.php index 7bfae960..bd6067fb 100644 --- a/src/System/Integrate/ValueObjects/CommandMap.php +++ b/src/System/Integrate/ValueObjects/CommandMap.php @@ -51,6 +51,9 @@ public function mode(): string */ public function patterns() { + if (false === array_key_exists('pattern', $this->command)) { + return []; + } $pattern = $this->command['pattern']; return is_array($pattern) ? $pattern : [$pattern]; @@ -77,6 +80,11 @@ public function fn() return $this->command['fn'] ?? 'main'; } + public function method(): string + { + return is_array($this->fn()) ? $this->fn()[1] : $this->fn(); + } + /** * @return array */ diff --git a/tests/Integrate/Commands/HelpCommandsTest.php b/tests/Integrate/Commands/HelpCommandsTest.php index d06dbc7c..0bae9264 100644 --- a/tests/Integrate/Commands/HelpCommandsTest.php +++ b/tests/Integrate/Commands/HelpCommandsTest.php @@ -4,6 +4,7 @@ namespace System\Test\Integrate\Commands; +use System\Console\Command; use System\Integrate\Console\HelpCommand; final class HelpCommandsTest extends CommandTest @@ -39,6 +40,46 @@ public function itCanCallHelpCommandMain() $this->assertSuccess($exit); } + /** + * @test + */ + public function itCanCallHelpCommandMainWithRegesterAnotherCommand() + { + $helpCommand = new class(['php', 'cli', '--help']) extends HelpCommand { + protected array $commands = [ + [ + 'pattern' => 'test', + 'fn' => [RegisterHelpCommand::class, 'main'], + ], + ]; + + public function useCommands($commands): void + { + $this->commands = $commands; + } + }; + + ob_start(); + $exit = $helpCommand->main(); + $out = ob_get_clean(); + + $this->assertSuccess($exit); + $this->assertContain('some test will appere in test', $out); + $this->assertContain('this also will display in test', $out); + + // use old style commandmaps + $helpCommand->useCommands([ + ['class' => RegisterHelpCommand::class], + ]); + ob_start(); + $exit = $helpCommand->main(); + $out = ob_get_clean(); + + $this->assertSuccess($exit); + $this->assertContain('some test will appere in test', $out); + $this->assertContain('this also will display in test', $out); + } + /** * @test */ @@ -52,6 +93,34 @@ public function itCanCallHelpCommandCommandList() $this->assertSuccess($exit); } + /** + * @test + */ + public function itCanCallHelpCommandCommandListWithRegisterAnotherCommand() + { + $helpCommand = new class(['php', 'cli', '--list']) extends HelpCommand { + protected array $commands = [ + [ + 'pattern' => 'unit:test', + 'fn' => [RegisterHelpCommand::class, 'main'], + ], + ]; + + public function useCommands($commands): void + { + $this->commands = $commands; + } + }; + + ob_start(); + $exit = $helpCommand->commandList(); + $out = ob_get_clean(); + + $this->assertContain('unit:test', $out); + $this->assertContain('System\Test\Integrate\Commands\RegisterHelpCommand', $out); + $this->assertSuccess($exit); + } + /** * @test */ @@ -94,3 +163,24 @@ public function itCanCallHelpCommandCommandHelpButNoResult() $this->assertContain('php cli help ', $out); } } + +class RegisterHelpCommand extends Command +{ + /** + * @return array> + */ + public function printHelp() + { + return [ + 'commands' => [ + 'test' => 'some test will appere in test', + ], + 'options' => [ + '--test' => 'this also will display in test', + ], + 'relation' => [ + 'test' => ['[unit]'], + ], + ]; + } +}