Skip to content

Commit

Permalink
Merge pull request #28 from WebFiori/dev
Browse files Browse the repository at this point in the history
feat: Added Support for Running Command from Another
  • Loading branch information
usernane authored Aug 20, 2024
2 parents 78d40a3 + f5d4799 commit d9fc581
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 8 deletions.
1 change: 1 addition & 0 deletions tests/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
24 changes: 24 additions & 0 deletions tests/webfiori/tests/cli/RunnerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
19 changes: 19 additions & 0 deletions tests/webfiori/tests/cli/testCommands/Command03.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php
namespace webfiori\tests\cli\testCommands;

use webfiori\cli\CLICommand;

class Command03 extends CLICommand {
public function __construct() {
parent::__construct('run-another');
}

public function exec(): int {
$this->println('Running Sub Command');
$this->getOwner()->register(new Command01());
$this->execSubCommand('show-v', ['arg-3' => 'Ur']);
$this->println('Done');
return 0;
}

}
50 changes: 42 additions & 8 deletions webfiori/cli/CLICommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,6 @@ public function confirm(string $confirmTxt, bool $default = null) : bool {
public function error(string $message) {
$this->printMsg($message, 'Error', 'light-red');
}

/**
* Execute the command.
*
Expand All @@ -320,17 +319,23 @@ 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;
Expand All @@ -347,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.
*
Expand Down Expand Up @@ -406,11 +438,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;
Expand Down
39 changes: 39 additions & 0 deletions webfiori/cli/Runner.php
Original file line number Diff line number Diff line change
Expand Up @@ -423,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.
Expand Down

0 comments on commit d9fc581

Please sign in to comment.