Improved context commands

This commit is contained in:
Chris 2016-11-01 16:10:35 +01:00
parent 01ee043bac
commit ae17abb6c1
3 changed files with 69 additions and 7 deletions

View File

@ -4,6 +4,7 @@ require_once __DIR__."/../vendor/autoload.php";
use NoccyLabs\Shell\Shell; use NoccyLabs\Shell\Shell;
use NoccyLabs\Shell\Command; use NoccyLabs\Shell\Command;
use NoccyLabs\Shell\Context;
class MyCommand extends Command class MyCommand extends Command
{ {
@ -13,6 +14,18 @@ class MyCommand extends Command
} }
} }
class MyContext extends Context
{
/**
* @args
* @help Useful test!
*/
public function test()
{
}
}
class MyShell extends Shell class MyShell extends Shell
{ {
@ -20,7 +33,8 @@ class MyShell extends Shell
protected function configure() protected function configure()
{ {
$context = $this->createContext(); $context = new MyContext();
$this->pushContext($context);
$context->addCommand("hello", function () { $context->addCommand("hello", function () {
echo "world\nthis\nis\na\ntest\n"; echo "world\nthis\nis\na\ntest\n";
}); });

View File

@ -8,6 +8,8 @@ class Context
protected $commands = []; protected $commands = [];
protected $commandInfo = [];
protected $data = []; protected $data = [];
@ -21,11 +23,42 @@ class Context
protected function configure() protected function configure()
{ {
// Override this to do setup stuff // Override this to do setup stuff
$this->findCommands();
} }
public function addCommand($command, callable $handler) protected function findCommands()
{
$refl = new \ReflectionClass(get_called_class());
foreach ($refl->getMethods() as $method) {
$docblock = $method->getDocComment();
$lines = array_map(function ($line) {
return trim($line, "*/ \t");
}, explode("\n", $docblock));
$info = [];
foreach ($lines as $line) {
if (preg_match("/^@(command|help|args) (.+?)$/", $line, $match)) {
list($void,$key,$value) = $match;
$info[$key] = $value;
}
if (count($info)>0) {
$this->addCommand($method->getName(), [$this, $method->getName()], $info);
}
}
}
}
public function addCommand($command, callable $handler, array $info=[])
{ {
$this->commands[$command] = $handler; $this->commands[$command] = $handler;
$this->commandInfo[$command] = $info;
}
public function setCommandHelp($command, $help)
{
if (!array_key_exists($command, $this->commandInfo)) {
return;
}
$this->commandInfo[$command]['help'] = $help;
} }
public function addCommands(array $commands) public function addCommands(array $commands)
@ -50,6 +83,18 @@ class Context
return $this->commands[$command]; return $this->commands[$command];
} }
public function getCommandHelp()
{
$ret = [];
foreach ($this->commands as $command=>$handler) {
$info = $this->commandInfo[$command];
$args = array_key_exists("args",$info)?$info['args']:"";
$help = array_key_exists("help",$info)?$info['help']:"";
$ret[trim("{$command} {$args}")] = $help;
}
return $ret;
}
public function getName() public function getName()
{ {
return $this->name; return $this->name;

View File

@ -210,11 +210,14 @@ class Shell
$this->popContext(); $this->popContext();
break; break;
case 'help': case 'help':
echo $help = $this->context->getCommandHelp();
"Built in commands:\n". printf("Commands in current context:\n\n");
" . Show current context\n". foreach ($help as $command=>$info) {
" .. Go to parent context\n". printf(" %-20s %s\n", $command, $info);
" exit Exit the shell\n"; }
printf("\nGlobal commands:\n\n");
printf(" %-20s %s\n", "exit", "Leave the shell");
printf(" %-20s %s\n", "..", "Discard the current context and go to parent");
break; break;
case 'exit': case 'exit':
$this->stop(); $this->stop();