Skip to content

Commit

Permalink
Added Support for Callbacks to Execute After Each Command
Browse files Browse the repository at this point in the history
  • Loading branch information
usernane committed Feb 8, 2023
1 parent e627d2f commit 7fa690d
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 12 deletions.
42 changes: 40 additions & 2 deletions tests/webfiori/tests/cli/RunnerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,9 @@ public function testRunner15() {
$runner->register(new Command00());
$runner->register(new HelpCommand());
$runner->register(new WithExceptionCommand());
$runner->setAfterExecution(function (Runner $r) {
$r->getActiveCommand()->println('Command Exit Status: '.$r->getLastCommandExitStatus());
});
$runner->setArgsVector([
'entry.php',
'--ansi',
Expand All @@ -391,11 +394,14 @@ public function testRunner15() {
">>  super-hero: A command to display hero's name.\n",
" Supported Arguments:\n",
" name: The name of the hero\n",
"Command Exit Status: 0\n",
">> Error: An exception was thrown.\n",
"Exception Message: Call to undefined method webfiori\\tests\\cli\\testCommands\\WithExceptionCommand::notExist()\n",
"Code: 0\n",
"At: ".ROOT_DIR."tests".DS."webfiori".DS."tests".DS."cli".DS."testCommands".DS."WithExceptionCommand.php\n",
"Line: 12\n",
">> "
"Command Exit Status: -1\n",
">> ",
], $runner->getOutput());
}
/**
Expand Down Expand Up @@ -434,6 +440,9 @@ public function testRunner18() {
$runner = new Runner();
$runner->register(new Command01());
$runner->setInput([]);
$runner->setAfterExecution(function (Runner $r) {
$r->getActiveCommand()->println('Command Exit Status: '.$r->getLastCommandExitStatus());
});
$this->assertEquals(0, $runner->runCommand(null, [
'show-v',
'arg-1' => 'Super Cool Arg',
Expand All @@ -443,7 +452,8 @@ public function testRunner18() {
"System version: 1.0.0\n",
"Super Cool Arg\n",
"First One is Coller\n",
"Hello\n"
"Hello\n",
"Command Exit Status: 0\n"
], $runner->getOutput());
}
/**
Expand Down Expand Up @@ -493,4 +503,32 @@ public function testRunner20() {
"Info: No command was specified to run.\n",
], $runner->getOutput());
}
/**
* @test
*/
public function testRunner21() {
$runner = new Runner();

$runner->register(new Command00());
$runner->register(new HelpCommand());
$runner->register(new WithExceptionCommand());
$runner->setAfterExecution(function (Runner $r) {
$r->getActiveCommand()->println('Command Exit Status: '.$r->getLastCommandExitStatus());
});

$runner->setArgsVector([
'entry.php',
'with-exception',
]);
$runner->setInput([]);
$runner->start();
$this->assertEquals([
"Error: An exception was thrown.\n",
"Exception Message: Call to undefined method webfiori\\tests\cli\\testCommands\WithExceptionCommand::notExist()\n",
"Code: 0\n",
"At: ".ROOT_DIR."tests\webfiori\\tests\cli\\testCommands\WithExceptionCommand.php\n",
"Line: 12\n",
"Command Exit Status: -1\n"
], $runner->getOutput());
}
}
56 changes: 46 additions & 10 deletions webfiori/cli/Runner.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ class Runner {
private $commandExitVal;
private $argsV;
private $isAnsi;
/**
* An array that holds sub-arrays for callbacks that will be executed
* each time a command finish execution.
*
* @var array
*/
private $afterRunPool;
/**
* An associative array that contains supported commands.
*
Expand Down Expand Up @@ -70,6 +77,7 @@ public function __construct() {
$this->inputStream = new StdIn();
$this->outputStream = new StdOut();
$this->commandExitVal = 0;
$this->afterRunPool = [];

$this->addArg('--ansi', [
'optional' => true,
Expand All @@ -82,6 +90,24 @@ public function __construct() {
$r->checkIsIntr();
});
}
/**
* Add a function to execute after every command.
*
* The method can be used to set multiple callbacks.
*
* @param callable $func The function that will be executed after the
* completion of command execution. The first parameter of the method
* will always be an instance of 'Runner' (e.g. function (Runner $runner){}).
*
* @param array $params Any additional parameters that will be passed to the
* callback.
*/
public function setAfterExecution(callable $func, array $params = []) {
$this->afterRunPool[] = [
'func' => $func,
'params' => $params
];
}
/**
* Adds a global command argument.
*
Expand Down Expand Up @@ -397,11 +423,28 @@ public function runCommand(CLICommand $c = null, array $args = [], bool $ansi =
}
$this->setArgV($args);
$this->setActiveCommand($c);
$this->commandExitVal = $c->excCommand();

try {
$this->commandExitVal = $c->excCommand();
} catch (Throwable $ex) {
$this->printMsg('An exception was thrown.', 'Error:', 'red');
$this->printMsg($ex->getMessage(), 'Exception Message:', 'yellow');
$this->printMsg($ex->getCode(), 'Code:', 'yellow');
$this->printMsg($ex->getFile(), 'At:', 'yellow');
$this->printMsg($ex->getLine(), 'Line:', 'yellow');
$this->commandExitVal = $ex->getCode() == 0 ? -1 : $ex->getCode();
}

$this->invokeAfterExc();
$this->setActiveCommand();

return $this->commandExitVal;
}
private function invokeAfterExc() {
foreach ($this->afterRunPool as $funcArr) {
call_user_func_array($funcArr['func'], array_merge([$this], $funcArr['params']));
}
}

/**
* Sets the command which is currently in execution stage.
*
Expand Down Expand Up @@ -526,14 +569,7 @@ public function start() : int {
} else if ($args[0] == 'exit') {
return 0;
} else {
try {
$this->runCommand(null, $args, $this->isAnsi);
} catch (Throwable $ex) {
$this->printMsg('An exception was thrown.', 'Error:', 'red');
$this->printMsg($ex->getMessage(), 'Exception Message:', 'yellow');
$this->printMsg($ex->getFile(), 'At:', 'yellow');
$this->printMsg($ex->getLine(), 'Line:', 'yellow');
}
$this->runCommand(null, $args, $this->isAnsi);
}
$this->printMsg('', '>>', 'blue');
}
Expand Down

0 comments on commit 7fa690d

Please sign in to comment.