83e1dcead53c6b0b07bd0f5901c9717fdc97f609
[yaffs-website] / vendor / psy / psysh / src / Command / Command.php
1 <?php
2
3 /*
4  * This file is part of Psy Shell.
5  *
6  * (c) 2012-2018 Justin Hileman
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 Psy\Command;
13
14 use Psy\Shell;
15 use Symfony\Component\Console\Application;
16 use Symfony\Component\Console\Command\Command as BaseCommand;
17 use Symfony\Component\Console\Helper\Table;
18 use Symfony\Component\Console\Helper\TableHelper;
19 use Symfony\Component\Console\Helper\TableStyle;
20 use Symfony\Component\Console\Output\OutputInterface;
21
22 /**
23  * The Psy Shell base command.
24  */
25 abstract class Command extends BaseCommand
26 {
27     /**
28      * Sets the application instance for this command.
29      *
30      * @param Application $application An Application instance
31      *
32      * @api
33      */
34     public function setApplication(Application $application = null)
35     {
36         if ($application !== null && !$application instanceof Shell) {
37             throw new \InvalidArgumentException('PsySH Commands require an instance of Psy\Shell');
38         }
39
40         return parent::setApplication($application);
41     }
42
43     /**
44      * {@inheritdoc}
45      */
46     public function asText()
47     {
48         $messages = [
49             '<comment>Usage:</comment>',
50             ' ' . $this->getSynopsis(),
51             '',
52         ];
53
54         if ($this->getAliases()) {
55             $messages[] = $this->aliasesAsText();
56         }
57
58         if ($this->getArguments()) {
59             $messages[] = $this->argumentsAsText();
60         }
61
62         if ($this->getOptions()) {
63             $messages[] = $this->optionsAsText();
64         }
65
66         if ($help = $this->getProcessedHelp()) {
67             $messages[] = '<comment>Help:</comment>';
68             $messages[] = ' ' . str_replace("\n", "\n ", $help) . "\n";
69         }
70
71         return implode("\n", $messages);
72     }
73
74     /**
75      * {@inheritdoc}
76      */
77     private function getArguments()
78     {
79         $hidden = $this->getHiddenArguments();
80
81         return array_filter($this->getNativeDefinition()->getArguments(), function ($argument) use ($hidden) {
82             return !in_array($argument->getName(), $hidden);
83         });
84     }
85
86     /**
87      * These arguments will be excluded from help output.
88      *
89      * @return array
90      */
91     protected function getHiddenArguments()
92     {
93         return ['command'];
94     }
95
96     /**
97      * {@inheritdoc}
98      */
99     private function getOptions()
100     {
101         $hidden = $this->getHiddenOptions();
102
103         return array_filter($this->getNativeDefinition()->getOptions(), function ($option) use ($hidden) {
104             return !in_array($option->getName(), $hidden);
105         });
106     }
107
108     /**
109      * These options will be excluded from help output.
110      *
111      * @return array
112      */
113     protected function getHiddenOptions()
114     {
115         return ['verbose'];
116     }
117
118     /**
119      * Format command aliases as text..
120      *
121      * @return string
122      */
123     private function aliasesAsText()
124     {
125         return '<comment>Aliases:</comment> <info>' . implode(', ', $this->getAliases()) . '</info>' . PHP_EOL;
126     }
127
128     /**
129      * Format command arguments as text.
130      *
131      * @return string
132      */
133     private function argumentsAsText()
134     {
135         $max = $this->getMaxWidth();
136         $messages = [];
137
138         $arguments = $this->getArguments();
139         if (!empty($arguments)) {
140             $messages[] = '<comment>Arguments:</comment>';
141             foreach ($arguments as $argument) {
142                 if (null !== $argument->getDefault() && (!is_array($argument->getDefault()) || count($argument->getDefault()))) {
143                     $default = sprintf('<comment> (default: %s)</comment>', $this->formatDefaultValue($argument->getDefault()));
144                 } else {
145                     $default = '';
146                 }
147
148                 $description = str_replace("\n", "\n" . str_pad('', $max + 2, ' '), $argument->getDescription());
149
150                 $messages[] = sprintf(" <info>%-${max}s</info> %s%s", $argument->getName(), $description, $default);
151             }
152
153             $messages[] = '';
154         }
155
156         return implode(PHP_EOL, $messages);
157     }
158
159     /**
160      * Format options as text.
161      *
162      * @return string
163      */
164     private function optionsAsText()
165     {
166         $max = $this->getMaxWidth();
167         $messages = [];
168
169         $options = $this->getOptions();
170         if ($options) {
171             $messages[] = '<comment>Options:</comment>';
172
173             foreach ($options as $option) {
174                 if ($option->acceptValue() && null !== $option->getDefault() && (!is_array($option->getDefault()) || count($option->getDefault()))) {
175                     $default = sprintf('<comment> (default: %s)</comment>', $this->formatDefaultValue($option->getDefault()));
176                 } else {
177                     $default = '';
178                 }
179
180                 $multiple = $option->isArray() ? '<comment> (multiple values allowed)</comment>' : '';
181                 $description = str_replace("\n", "\n" . str_pad('', $max + 2, ' '), $option->getDescription());
182
183                 $optionMax = $max - strlen($option->getName()) - 2;
184                 $messages[] = sprintf(
185                     " <info>%s</info> %-${optionMax}s%s%s%s",
186                     '--' . $option->getName(),
187                     $option->getShortcut() ? sprintf('(-%s) ', $option->getShortcut()) : '',
188                     $description,
189                     $default,
190                     $multiple
191                 );
192             }
193
194             $messages[] = '';
195         }
196
197         return implode(PHP_EOL, $messages);
198     }
199
200     /**
201      * Calculate the maximum padding width for a set of lines.
202      *
203      * @return int
204      */
205     private function getMaxWidth()
206     {
207         $max = 0;
208
209         foreach ($this->getOptions() as $option) {
210             $nameLength = strlen($option->getName()) + 2;
211             if ($option->getShortcut()) {
212                 $nameLength += strlen($option->getShortcut()) + 3;
213             }
214
215             $max = max($max, $nameLength);
216         }
217
218         foreach ($this->getArguments() as $argument) {
219             $max = max($max, strlen($argument->getName()));
220         }
221
222         return ++$max;
223     }
224
225     /**
226      * Format an option default as text.
227      *
228      * @param mixed $default
229      *
230      * @return string
231      */
232     private function formatDefaultValue($default)
233     {
234         if (is_array($default) && $default === array_values($default)) {
235             return sprintf("array('%s')", implode("', '", $default));
236         }
237
238         return str_replace("\n", '', var_export($default, true));
239     }
240
241     /**
242      * Get a Table instance.
243      *
244      * Falls back to legacy TableHelper.
245      *
246      * @return Table|TableHelper
247      */
248     protected function getTable(OutputInterface $output)
249     {
250         if (!class_exists('Symfony\Component\Console\Helper\Table')) {
251             return $this->getTableHelper();
252         }
253
254         $style = new TableStyle();
255         $style
256             ->setVerticalBorderChar(' ')
257             ->setHorizontalBorderChar('')
258             ->setCrossingChar('');
259
260         $table = new Table($output);
261
262         return $table
263             ->setRows([])
264             ->setStyle($style);
265     }
266
267     /**
268      * Legacy fallback for getTable.
269      *
270      * @return TableHelper
271      */
272     protected function getTableHelper()
273     {
274         $table = $this->getApplication()->getHelperSet()->get('table');
275
276         return $table
277             ->setRows([])
278             ->setLayout(TableHelper::LAYOUT_BORDERLESS)
279             ->setHorizontalBorderChar('')
280             ->setCrossingChar('');
281     }
282 }