From 455574b6a5bc541ced271f4bc3aaba72e6adeedf Mon Sep 17 00:00:00 2001 From: Christopher Vagnetoft Date: Wed, 2 Nov 2016 22:49:19 +0100 Subject: [PATCH] Fixed issue with global commands in parent contexts --- examples/simple.php | 23 ++++++++++++++++++++++ lib/Context.php | 8 +++++++- lib/Shell.php | 47 +++++++++++++++++++++++++++++++++++---------- 3 files changed, 67 insertions(+), 11 deletions(-) diff --git a/examples/simple.php b/examples/simple.php index 95b0749..6596576 100644 --- a/examples/simple.php +++ b/examples/simple.php @@ -20,6 +20,29 @@ class MyContext extends Context * @command testme * @args * @help Useful test! + * @global + */ + public function test() + { + echo "Test\n"; + } + + /** + * @command context + * @help Create a new context + */ + public function context() + { + return new OtherContext("newcontext"); + } +} + +class OtherContext extends Context +{ + /** + * @command other + * @args + * @help Other test */ public function test() { diff --git a/lib/Context.php b/lib/Context.php index e1dd132..0c791d5 100644 --- a/lib/Context.php +++ b/lib/Context.php @@ -71,7 +71,7 @@ class Context }, explode("\n", $docblock)); $info = []; foreach ($lines as $line) { - if (preg_match("/^@(command|help|args) (.+?)$/", $line, $match)) { + if (preg_match("/^@(command|help|args|global)\\s*(.*)$/", $line, $match)) { list($void,$key,$value) = $match; $info[$key] = $value; } @@ -132,6 +132,12 @@ class Context return $ret; } + public function isCommandGlobal($command) + { + $info = $this->commandInfo[$command]; + return array_key_exists('global', $info); + } + public function getName() { return $this->name; diff --git a/lib/Shell.php b/lib/Shell.php index 7576da7..5b971f5 100644 --- a/lib/Shell.php +++ b/lib/Shell.php @@ -176,12 +176,18 @@ class Shell private function findCommand($command) { // Go over current context and walk through stack until finding command - foreach(array_merge([ $this->context ] , $this->contextStack) as $context) { - if ($context->hasCommand($command)) { - $handler = $context->getCommand($command); - break; + if ($this->context->hasCommand($command)) { + $handler = $this->context->getCommand($command); + } else { + foreach($this->contextStack as $context) { + if ($context->hasCommand($command) && $context->isCommandGlobal($command)) { + $handler = $context->getCommand($command); + break; + } } } + + // No handler... if (empty($handler)) { return false; } @@ -236,13 +242,34 @@ class Shell break; case 'help': $help = $this->context->getCommandHelp(); - printf("Commands in current context:\n\n"); - foreach ($help as $command=>$info) { - printf(" %-20s %s\n", $command, $info); + $ghelp = []; + foreach ($this->contextStack as $context) { + $commands = $context->getCommandHelp(); + foreach ($commands as $command=>$info) { + if (strpos(" ",$command)!==false) { + list ($cmd,$arg)=explode(" ",$command,2); + } else { + $cmd = $command; + } + if ($context->isCommandGlobal($cmd)) { + $ghelp[$command] = $info; + } + } } - 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"); + ksort($ghelp); + printf("Commands in current context:\n"); + foreach ($help as $command=>$info) { + printf(" %-20s %s\n", $command, $info); + } + if (count($ghelp)) { + printf("\nImported from parent contexts:\n"); + foreach ($ghelp as $command=>$info) { + printf(" %-20s %s\n", $command, $info); + } + } + printf("\nGlobal commands:\n"); + printf(" %-20s %s\n", "exit", "Leave the shell"); + printf(" %-20s %s\n", "..", "Discard the current context and go to parent"); break; case 'exit': $this->stop();