Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
158 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
<?php | ||
|
||
namespace Symfony\Components\Console; | ||
|
||
use Symfony\Components\Console\Application; | ||
use Symfony\Components\Console\Input\StringInput; | ||
use Symfony\Components\Console\Output\ConsoleOutput; | ||
|
||
/* | ||
* This file is part of the symfony framework. | ||
* | ||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com> | ||
* | ||
* This source file is subject to the MIT license that is bundled | ||
* with this source code in the file LICENSE. | ||
*/ | ||
|
||
/** | ||
* A Shell wraps an Application to add shell capabilities to it. | ||
* | ||
* This class only works with a PHP compiled with readline support | ||
* (either --with-readline or --with-libedit) | ||
* | ||
* @package symfony | ||
* @subpackage cli | ||
* @author Fabien Potencier <fabien.potencier@symfony-project.com> | ||
*/ | ||
class Shell | ||
{ | ||
protected $application; | ||
protected $history; | ||
protected $output; | ||
|
||
/** | ||
* Constructor. | ||
* | ||
* If there is no readline support for the current PHP executable | ||
* a \RuntimeException exception is thrown. | ||
* | ||
* @param Application $application An application instance | ||
*/ | ||
public function __construct(Application $application) | ||
{ | ||
if (!function_exists('readline')) | ||
{ | ||
throw new \RuntimeException('Unable to start the shell as the Readline extension is not enabled.'); | ||
} | ||
|
||
$this->application = $application; | ||
$this->history = getenv('HOME').'/.history_'.$application->getName(); | ||
$this->output = new ConsoleOutput(); | ||
} | ||
|
||
/** | ||
* Runs the shell. | ||
*/ | ||
public function run() | ||
{ | ||
$this->application->setAutoExit(false); | ||
$this->application->setCatchExceptions(true); | ||
|
||
readline_read_history($this->history); | ||
readline_completion_function(array($this, 'autocompleter')); | ||
|
||
$this->output->write($this->getHeader()); | ||
while (true) | ||
{ | ||
$command = readline($this->application->getName().' > '); | ||
|
||
if (false === $command) | ||
{ | ||
$this->output->write("\n"); | ||
|
||
break; | ||
} | ||
|
||
readline_add_history($command); | ||
readline_write_history($this->history); | ||
|
||
if (0 !== $ret = $this->application->run(new StringInput($command), $this->output)) | ||
{ | ||
$this->output->write(sprintf('<error>The command terminated with an error status (%s)</error>', $ret)); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Tries to return autocompletion for the current entered text. | ||
* | ||
* @param string $text The last segment of the entered text | ||
* @param integer $position The current position | ||
*/ | ||
protected function autocompleter($text, $position) | ||
{ | ||
$info = readline_info(); | ||
$text = substr($info['line_buffer'], 0, $info['end']); | ||
|
||
if ($info['point'] !== $info['end']) | ||
{ | ||
return true; | ||
} | ||
|
||
// task name? | ||
if (false === strpos($text, ' ') || !$text) | ||
{ | ||
return array_keys($this->application->getCommands()); | ||
} | ||
|
||
// options and arguments? | ||
try | ||
{ | ||
$command = $this->application->findCommand(substr($text, 0, strpos($text, ' '))); | ||
} | ||
catch (\Exception $e) | ||
{ | ||
return true; | ||
} | ||
|
||
$list = array('--help'); | ||
foreach ($command->getDefinition()->getOptions() as $option) | ||
{ | ||
$list[] = '--'.$option->getName(); | ||
} | ||
|
||
return $list; | ||
} | ||
|
||
/** | ||
* Returns the shell header. | ||
* | ||
* @return string The header string | ||
*/ | ||
protected function getHeader() | ||
{ | ||
return <<<EOF | ||
Welcome to the <info>{$this->application->getName()}</info> shell. | ||
At the prompt, type <comment>help</comment> for some help, | ||
or <comment>list</comment> to get a list available commands. | ||
To exist the shell, type <comment>^D</comment>. | ||
EOF; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters