From 02b53becbb1211ca5b5f00575fb15586e9d8e9f4 Mon Sep 17 00:00:00 2001 From: Ibrahim BinAlshikh Date: Tue, 20 Aug 2024 15:40:07 +0300 Subject: [PATCH 1/4] refactor: Code Enhancements --- webfiori/cli/CLICommand.php | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/webfiori/cli/CLICommand.php b/webfiori/cli/CLICommand.php index 9dc6563..7790a96 100644 --- a/webfiori/cli/CLICommand.php +++ b/webfiori/cli/CLICommand.php @@ -319,18 +319,26 @@ public function error(string $message) { */ public function excCommand() : int { $retVal = -1; - - foreach ($this->getOwner()->getArgs() as $arg) { - $this->addArgument($arg); + + $owner = $this->getOwner(); + + if ($owner !== null) { + + foreach ($owner->getArgs() as $arg) { + $this->addArgument($arg); + } } if ($this->parseArgsHelper() && $this->checkIsArgsSetHelper()) { $retVal = $this->exec(); } - foreach ($this->getOwner()->getArgs() as $arg) { - $this->removeArgument($arg->getName()); - $arg->resetValue(); + if ($owner !== null) { + + foreach ($owner->getArgs() as $arg) { + $this->removeArgument($arg->getName()); + $arg->resetValue(); + } } return $retVal; @@ -406,11 +414,13 @@ public function getArgValue(string $optionName) { $arg = $this->getArg($trimmedOptName); if ($arg !== null) { - if ($arg->getValue() !== null && !($this->getOwner() !== null && $this->getOwner()->isInteractive())) { + $owner = $this->getOwner(); + + if ($arg->getValue() !== null && !($owner !== null && $owner->isInteractive())) { return $arg->getValue(); } - return Argument::extractValue($trimmedOptName, $this->getOwner()); + return Argument::extractValue($trimmedOptName, $owner); } return null; From be221b7a1e8802aeb49e94b3157ec726555b32e7 Mon Sep 17 00:00:00 2001 From: Ibrahim BinAlshikh Date: Tue, 20 Aug 2024 23:50:42 +0300 Subject: [PATCH 2/4] feat: Added Support for Running Command from Another --- tests/bootstrap.php | 1 + tests/webfiori/tests/cli/RunnerTest.php | 24 +++++++++++++++ webfiori/cli/CLICommand.php | 28 +++++++++++++++++- webfiori/cli/Runner.php | 39 +++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 1 deletion(-) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 71b6041..e22b48c 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -55,6 +55,7 @@ require_once $rootDir.'/tests/webfiori/tests/cli/TestCommand.php'; require_once $rootDir.'/tests/webfiori/tests/cli/testCommands/Command00.php'; require_once $rootDir.'/tests/webfiori/tests/cli/testCommands/Command01.php'; +require_once $rootDir.'/tests/webfiori/tests/cli/testCommands/Command03.php'; require_once $rootDir.'/tests/webfiori/tests/cli/testCommands/WithExceptionCommand.php'; require_once $rootDir.'/tests/webfiori/tests/TestStudent.php'; require_once $rootDir.'/tests/webfiori/tests/TestStudent2.php'; diff --git a/tests/webfiori/tests/cli/RunnerTest.php b/tests/webfiori/tests/cli/RunnerTest.php index 43139dd..27e0a75 100644 --- a/tests/webfiori/tests/cli/RunnerTest.php +++ b/tests/webfiori/tests/cli/RunnerTest.php @@ -542,6 +542,30 @@ public function testRunner21() { "Command Exit Status: -1\n" ], $output); } + public function testRunner22() { + $runner = new Runner(); + $runner->register(new testCommands\Command03()); + $runner->setArgsVector([ + 'entry.php', + 'run-another', + 'arg-1' => 'Nice', + 'arg-2' => 'Cool' + ]); + $runner->setInputStream(new ArrayInputStream([ + + ])); + $runner->setOutputStream(new ArrayOutputStream()); + $exitCode = $runner->start(); + $output = $runner->getOutput(); + $this->assertEquals([ + "Running Sub Command\n", + "System version: 1.0.0\n", + "Nice\n", + "Cool\n", + "Ur\n", + "Done\n", + ], $output); + } /** * @test */ diff --git a/webfiori/cli/CLICommand.php b/webfiori/cli/CLICommand.php index 7790a96..5660fc0 100644 --- a/webfiori/cli/CLICommand.php +++ b/webfiori/cli/CLICommand.php @@ -306,7 +306,33 @@ public function confirm(string $confirmTxt, bool $default = null) : bool { public function error(string $message) { $this->printMsg($message, 'Error', 'light-red'); } - + /** + * Execute a registered command using a sub-runner. + * + * This method can be used to execute a registered command within the runner + * using another + * runner instance which shares argsv, input and output streams with the + * main runner. It can be used to invoke another command from within a + * running command. + * + * @param string $name The name of the command. It must be a part of + * registered commands. + * + * @param array $additionalArgs An associative array that represents additional arguments + * to be passed to the command. + * + * @return int The method will return an integer that represent exit status + * code of the command after execution. + */ + public function execSubCommand(string $name, $additionalArgs = []) : int { + $owner = $this->getOwner(); + + if ($owner === null) { + return -1; + } + + return $owner->runCommandAsSub($name, $additionalArgs); + } /** * Execute the command. * diff --git a/webfiori/cli/Runner.php b/webfiori/cli/Runner.php index 719b8f1..890edd7 100644 --- a/webfiori/cli/Runner.php +++ b/webfiori/cli/Runner.php @@ -351,6 +351,45 @@ public function reset() : Runner { return $this; } + /** + * Execute a registered command using a sub-runner. + * + * This method can be used to execute a registered command using another + * runner instance which shares argsv, input and output streams with the + * main runner. It can be used to invoke another command from within a + * running command. + * + * @param string $commandName The name of the command. It must be a part of + * registered commands. + * + * @param array $additionalArgs An associative array that represents additional arguments + * to be passed to the command. + * + * @return int The method will return an integer that represent exit status + * code of the command after execution. + */ + public function runCommandAsSub(string $commandName, array $additionalArgs = []) : int { + $c = $this->getCommandByName($commandName); + + if ($c === null) { + return -1; + } + $subRunner = new Runner(); + $subRunner->setInputStream($this->getInputStream()); + $subRunner->setOutputStream($this->getOutputStream()); + $subRunner->register($c); + $args = $this->getArgsVector(); + $args[0] = $commandName; + $code = $subRunner->runCommand(null, array_merge($args, $additionalArgs), $this->isAnsi); + + if ($code != 0) { + if ($this->getActiveCommand() !== null) { + $this->getActiveCommand()->warning('Command "'.$commandName.'" exited with code '.$code.'.'); + } + } + + return $code; + } /** * Executes a command given as object. * From a83c899349042e5312aee77a17c65687159600a9 Mon Sep 17 00:00:00 2001 From: Ibrahim BinAlshikh Date: Wed, 21 Aug 2024 00:02:12 +0300 Subject: [PATCH 3/4] Create Command03.php --- .../tests/cli/testCommands/Command03.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 tests/webfiori/tests/cli/testCommands/Command03.php diff --git a/tests/webfiori/tests/cli/testCommands/Command03.php b/tests/webfiori/tests/cli/testCommands/Command03.php new file mode 100644 index 0000000..86a9448 --- /dev/null +++ b/tests/webfiori/tests/cli/testCommands/Command03.php @@ -0,0 +1,19 @@ +println('Running Sub Command'); + $this->getOwner()->register(new Command01()); + $this->execSubCommand('show-v', ['arg-3' => 'Ur']); + $this->println('Done'); + return 0; + } + +} From f5d47993c886aa74b8ea5c74922ecebb89886c51 Mon Sep 17 00:00:00 2001 From: Ibrahim BinAlshikh Date: Wed, 21 Aug 2024 00:04:25 +0300 Subject: [PATCH 4/4] chore: Run CS Fixer --- webfiori/cli/CLICommand.php | 62 ++++++++++++++--------------- webfiori/cli/Runner.php | 78 ++++++++++++++++++------------------- 2 files changed, 69 insertions(+), 71 deletions(-) diff --git a/webfiori/cli/CLICommand.php b/webfiori/cli/CLICommand.php index 5660fc0..34ab7a2 100644 --- a/webfiori/cli/CLICommand.php +++ b/webfiori/cli/CLICommand.php @@ -306,33 +306,6 @@ public function confirm(string $confirmTxt, bool $default = null) : bool { public function error(string $message) { $this->printMsg($message, 'Error', 'light-red'); } - /** - * Execute a registered command using a sub-runner. - * - * This method can be used to execute a registered command within the runner - * using another - * runner instance which shares argsv, input and output streams with the - * main runner. It can be used to invoke another command from within a - * running command. - * - * @param string $name The name of the command. It must be a part of - * registered commands. - * - * @param array $additionalArgs An associative array that represents additional arguments - * to be passed to the command. - * - * @return int The method will return an integer that represent exit status - * code of the command after execution. - */ - public function execSubCommand(string $name, $additionalArgs = []) : int { - $owner = $this->getOwner(); - - if ($owner === null) { - return -1; - } - - return $owner->runCommandAsSub($name, $additionalArgs); - } /** * Execute the command. * @@ -345,11 +318,10 @@ public function execSubCommand(string $name, $additionalArgs = []) : int { */ public function excCommand() : int { $retVal = -1; - + $owner = $this->getOwner(); - + if ($owner !== null) { - foreach ($owner->getArgs() as $arg) { $this->addArgument($arg); } @@ -360,7 +332,6 @@ public function excCommand() : int { } if ($owner !== null) { - foreach ($owner->getArgs() as $arg) { $this->removeArgument($arg->getName()); $arg->resetValue(); @@ -381,6 +352,33 @@ public function excCommand() : int { * */ public abstract function exec() : int; + /** + * Execute a registered command using a sub-runner. + * + * This method can be used to execute a registered command within the runner + * using another + * runner instance which shares argsv, input and output streams with the + * main runner. It can be used to invoke another command from within a + * running command. + * + * @param string $name The name of the command. It must be a part of + * registered commands. + * + * @param array $additionalArgs An associative array that represents additional arguments + * to be passed to the command. + * + * @return int The method will return an integer that represent exit status + * code of the command after execution. + */ + public function execSubCommand(string $name, $additionalArgs = []) : int { + $owner = $this->getOwner(); + + if ($owner === null) { + return -1; + } + + return $owner->runCommandAsSub($name, $additionalArgs); + } /** * Returns an object that holds argument info if the command. * @@ -441,7 +439,7 @@ public function getArgValue(string $optionName) { if ($arg !== null) { $owner = $this->getOwner(); - + if ($arg->getValue() !== null && !($owner !== null && $owner->isInteractive())) { return $arg->getValue(); } diff --git a/webfiori/cli/Runner.php b/webfiori/cli/Runner.php index 890edd7..941f61d 100644 --- a/webfiori/cli/Runner.php +++ b/webfiori/cli/Runner.php @@ -351,45 +351,6 @@ public function reset() : Runner { return $this; } - /** - * Execute a registered command using a sub-runner. - * - * This method can be used to execute a registered command using another - * runner instance which shares argsv, input and output streams with the - * main runner. It can be used to invoke another command from within a - * running command. - * - * @param string $commandName The name of the command. It must be a part of - * registered commands. - * - * @param array $additionalArgs An associative array that represents additional arguments - * to be passed to the command. - * - * @return int The method will return an integer that represent exit status - * code of the command after execution. - */ - public function runCommandAsSub(string $commandName, array $additionalArgs = []) : int { - $c = $this->getCommandByName($commandName); - - if ($c === null) { - return -1; - } - $subRunner = new Runner(); - $subRunner->setInputStream($this->getInputStream()); - $subRunner->setOutputStream($this->getOutputStream()); - $subRunner->register($c); - $args = $this->getArgsVector(); - $args[0] = $commandName; - $code = $subRunner->runCommand(null, array_merge($args, $additionalArgs), $this->isAnsi); - - if ($code != 0) { - if ($this->getActiveCommand() !== null) { - $this->getActiveCommand()->warning('Command "'.$commandName.'" exited with code '.$code.'.'); - } - } - - return $code; - } /** * Executes a command given as object. * @@ -462,6 +423,45 @@ public function runCommand(CLICommand $c = null, array $args = [], bool $ansi = return $this->commandExitVal; } + /** + * Execute a registered command using a sub-runner. + * + * This method can be used to execute a registered command using another + * runner instance which shares argsv, input and output streams with the + * main runner. It can be used to invoke another command from within a + * running command. + * + * @param string $commandName The name of the command. It must be a part of + * registered commands. + * + * @param array $additionalArgs An associative array that represents additional arguments + * to be passed to the command. + * + * @return int The method will return an integer that represent exit status + * code of the command after execution. + */ + public function runCommandAsSub(string $commandName, array $additionalArgs = []) : int { + $c = $this->getCommandByName($commandName); + + if ($c === null) { + return -1; + } + $subRunner = new Runner(); + $subRunner->setInputStream($this->getInputStream()); + $subRunner->setOutputStream($this->getOutputStream()); + $subRunner->register($c); + $args = $this->getArgsVector(); + $args[0] = $commandName; + $code = $subRunner->runCommand(null, array_merge($args, $additionalArgs), $this->isAnsi); + + if ($code != 0) { + if ($this->getActiveCommand() !== null) { + $this->getActiveCommand()->warning('Command "'.$commandName.'" exited with code '.$code.'.'); + } + } + + return $code; + } /** * Sets the command which is currently in execution stage.