Rajout de doctrine/orm
[zf2.biz/galerie.git] / vendor / symfony / console / Symfony / Component / Console / Shell.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\Console;
13
14 use Symfony\Component\Console\Application;
15 use Symfony\Component\Console\Input\StringInput;
16 use Symfony\Component\Console\Output\ConsoleOutput;
17 use Symfony\Component\Process\ProcessBuilder;
18 use Symfony\Component\Process\PhpExecutableFinder;
19
20 /**
21  * A Shell wraps an Application to add shell capabilities to it.
22  *
23  * Support for history and completion only works with a PHP compiled
24  * with readline support (either --with-readline or --with-libedit)
25  *
26  * @author Fabien Potencier <fabien@symfony.com>
27  * @author Martin Hasoň <martin.hason@gmail.com>
28  */
29 class Shell
30 {
31     private $application;
32     private $history;
33     private $output;
34     private $hasReadline;
35     private $prompt;
36     private $processIsolation;
37
38     /**
39      * Constructor.
40      *
41      * If there is no readline support for the current PHP executable
42      * a \RuntimeException exception is thrown.
43      *
44      * @param Application $application An application instance
45      */
46     public function __construct(Application $application)
47     {
48         $this->hasReadline = function_exists('readline');
49         $this->application = $application;
50         $this->history = getenv('HOME').'/.history_'.$application->getName();
51         $this->output = new ConsoleOutput();
52         $this->prompt = $application->getName().' > ';
53         $this->processIsolation = false;
54     }
55
56     /**
57      * Runs the shell.
58      */
59     public function run()
60     {
61         $this->application->setAutoExit(false);
62         $this->application->setCatchExceptions(true);
63
64         if ($this->hasReadline) {
65             readline_read_history($this->history);
66             readline_completion_function(array($this, 'autocompleter'));
67         }
68
69         $this->output->writeln($this->getHeader());
70         $php = null;
71         if ($this->processIsolation) {
72             $finder = new PhpExecutableFinder();
73             $php = $finder->find();
74             $this->output->writeln(<<<EOF
75 <info>Running with process isolation, you should consider this:</info>
76   * each command is executed as separate process,
77   * commands don't support interactivity, all params must be passed explicitly,
78   * commands output is not colorized.
79
80 EOF
81             );
82         }
83
84         while (true) {
85             $command = $this->readline();
86
87             if (false === $command) {
88                 $this->output->writeln("\n");
89
90                 break;
91             }
92
93             if ($this->hasReadline) {
94                 readline_add_history($command);
95                 readline_write_history($this->history);
96             }
97
98             if ($this->processIsolation) {
99                 $pb = new ProcessBuilder();
100
101                 $process = $pb
102                     ->add($php)
103                     ->add($_SERVER['argv'][0])
104                     ->add($command)
105                     ->inheritEnvironmentVariables(true)
106                     ->getProcess()
107                 ;
108
109                 $output = $this->output;
110                 $process->run(function($type, $data) use ($output) {
111                     $output->writeln($data);
112                 });
113
114                 $ret = $process->getExitCode();
115             } else {
116                 $ret = $this->application->run(new StringInput($command), $this->output);
117             }
118
119             if (0 !== $ret) {
120                 $this->output->writeln(sprintf('<error>The command terminated with an error status (%s)</error>', $ret));
121             }
122         }
123     }
124
125     /**
126      * Returns the shell header.
127      *
128      * @return string The header string
129      */
130     protected function getHeader()
131     {
132         return <<<EOF
133
134 Welcome to the <info>{$this->application->getName()}</info> shell (<comment>{$this->application->getVersion()}</comment>).
135
136 At the prompt, type <comment>help</comment> for some help,
137 or <comment>list</comment> to get a list of available commands.
138
139 To exit the shell, type <comment>^D</comment>.
140
141 EOF;
142     }
143
144     /**
145      * Tries to return autocompletion for the current entered text.
146      *
147      * @param string $text The last segment of the entered text
148      *
149      * @return Boolean|array A list of guessed strings or true
150      */
151     private function autocompleter($text)
152     {
153         $info = readline_info();
154         $text = substr($info['line_buffer'], 0, $info['end']);
155
156         if ($info['point'] !== $info['end']) {
157             return true;
158         }
159
160         // task name?
161         if (false === strpos($text, ' ') || !$text) {
162             return array_keys($this->application->all());
163         }
164
165         // options and arguments?
166         try {
167             $command = $this->application->find(substr($text, 0, strpos($text, ' ')));
168         } catch (\Exception $e) {
169             return true;
170         }
171
172         $list = array('--help');
173         foreach ($command->getDefinition()->getOptions() as $option) {
174             $list[] = '--'.$option->getName();
175         }
176
177         return $list;
178     }
179
180     /**
181      * Reads a single line from standard input.
182      *
183      * @return string The single line from standard input
184      */
185     private function readline()
186     {
187         if ($this->hasReadline) {
188             $line = readline($this->prompt);
189         } else {
190             $this->output->write($this->prompt);
191             $line = fgets(STDIN, 1024);
192             $line = (!$line && strlen($line) == 0) ? false : rtrim($line);
193         }
194
195         return $line;
196     }
197
198     public function getProcessIsolation()
199     {
200         return $this->processIsolation;
201     }
202
203     public function setProcessIsolation($processIsolation)
204     {
205         $this->processIsolation = (Boolean) $processIsolation;
206     }
207 }