54f9808200f7a1425c4e07e5eed313e84639be88
[yaffs-website] / vendor / drupal / console-core / src / Descriptor / TextDescriptor.php
1 <?php
2 /*
3  * This file is part of the Symfony package.
4  *
5  * (c) Fabien Potencier <fabien@symfony.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10 namespace Drupal\Console\Core\Descriptor;
11
12 use Symfony\Component\Console\Application;
13 use Symfony\Component\Console\Command\Command;
14 use Symfony\Component\Console\Input\InputArgument;
15 use Symfony\Component\Console\Input\InputDefinition;
16 use Symfony\Component\Console\Input\InputOption;
17 use Symfony\Component\Console\Descriptor\Descriptor;
18 use Symfony\Component\Console\Descriptor\ApplicationDescription;
19
20 /**
21  * Text descriptor.
22  *
23  * @author Jean-François Simon <contact@jfsimon.fr>
24  *
25  * @internal
26  */
27 class TextDescriptor extends Descriptor
28 {
29     /**
30      * {@inheritdoc}
31      */
32     protected function describeInputArgument(InputArgument $argument, array $options = [])
33     {
34         if (null !== $argument->getDefault() && (!is_array($argument->getDefault()) || count($argument->getDefault()))) {
35             $default = sprintf('<comment> [default: %s]</comment>', $this->formatDefaultValue($argument->getDefault()));
36         } else {
37             $default = '';
38         }
39         $totalWidth = isset($options['total_width']) ? $options['total_width'] : strlen($argument->getName());
40         $spacingWidth = $totalWidth - strlen($argument->getName()) + 2;
41         $this->writeText(
42             sprintf(
43                 '  <info>%s</info>%s%s%s',
44                 $argument->getName(),
45                 str_repeat(' ', $spacingWidth),
46                 // + 17 = 2 spaces + <info> + </info> + 2 spaces
47                 preg_replace(
48                     '/\s*\R\s*/',
49                     PHP_EOL.str_repeat(' ', $totalWidth + 17),
50                     $options['translator']->trans($argument->getDescription())
51                 ),
52                 $default
53             ), $options
54         );
55     }
56     /**
57      * {@inheritdoc}
58      */
59     protected function describeInputOption(InputOption $option, array $options = [])
60     {
61         if ($option->acceptValue() && null !== $option->getDefault() && (!is_array($option->getDefault()) || count($option->getDefault()))) {
62             $default = sprintf('<comment> [default: %s]</comment>', $this->formatDefaultValue($option->getDefault()));
63         } else {
64             $default = '';
65         }
66         $value = '';
67         if ($option->acceptValue()) {
68             $value = '='.strtoupper($option->getName());
69             if ($option->isValueOptional()) {
70                 $value = '['.$value.']';
71             }
72         }
73         $totalWidth = isset($options['total_width']) ? $options['total_width'] : $this->calculateTotalWidthForOptions([$option]);
74         $synopsis = sprintf(
75             '%s%s',
76             $option->getShortcut() ? sprintf('-%s, ', $option->getShortcut()) : '    ',
77             sprintf('--%s%s', $option->getName(), $value)
78         );
79         $spacingWidth = $totalWidth - strlen($synopsis) + 2;
80         $this->writeText(
81             sprintf(
82                 '  <info>%s</info>%s%s%s%s',
83                 $synopsis,
84                 str_repeat(' ', $spacingWidth),
85                 // + 17 = 2 spaces + <info> + </info> + 2 spaces
86                 preg_replace(
87                     '/\s*\R\s*/',
88                     "\n".str_repeat(' ', $totalWidth + 17),
89                     $options['translator']->trans($option->getDescription())
90                 ),
91                 $default,
92                 $option->isArray() ? '<comment> (multiple values allowed)</comment>' : ''
93             ), $options
94         );
95     }
96     /**
97      * {@inheritdoc}
98      */
99     protected function describeInputDefinition(InputDefinition $definition, array $options = [])
100     {
101         $command_name = null;
102         if (array_key_exists('command', $options)) {
103             $command_name = $options['command']->getName();
104         }
105
106         $totalWidth = $this->calculateTotalWidthForOptions($definition->getOptions());
107         foreach ($definition->getArguments() as $argument) {
108             $totalWidth = max($totalWidth, strlen($argument->getName()));
109         }
110
111         if ($definition->getArguments()) {
112             $this->writeText($options['translator']->trans('commands.list.messages.arguments'), $options);
113             $this->writeText("\n");
114             foreach ($definition->getArguments() as $argument) {
115                 $this->describeInputArgument($argument, array_merge($options, ['total_width' => $totalWidth]));
116                 $this->writeText("\n");
117             }
118         }
119         if ($definition->getArguments() && $definition->getOptions()) {
120             $this->writeText("\n");
121         }
122         if ($definition->getOptions()) {
123             $laterOptions = [];
124             $this->writeText($options['translator']->trans('commands.list.messages.options'), $options);
125
126             $exitOptionName = 'help';
127             if ($command_name === $exitOptionName) {
128                 $exitOptionName = '';
129             }
130
131             foreach ($definition->getOptions() as $option) {
132                 if ($option->getName() === $exitOptionName) {
133                     break;
134                 }
135
136                 if (strlen($option->getShortcut()) > 1) {
137                     $laterOptions[] = $option;
138                     continue;
139                 }
140                 $this->writeText("\n");
141                 $this->describeInputOption($option, array_merge($options, ['total_width' => $totalWidth]));
142             }
143             foreach ($laterOptions as $option) {
144                 $this->writeText("\n");
145                 $this->describeInputOption($option, array_merge($options, ['total_width' => $totalWidth]));
146             }
147         }
148     }
149     /**
150      * {@inheritdoc}
151      */
152     protected function describeCommand(Command $command, array $options = [])
153     {
154         $namespace = substr(
155             $command->getName(),
156             0,
157             (strpos($command->getName(), ':')?:0)
158         );
159         $commandData = $command->getApplication()->getData();
160         $examples = [];
161         if (array_key_exists($namespace, $commandData['commands'])) {
162             $commands = $commandData['commands'][$namespace];
163             foreach ($commands as $item) {
164                 if ($item['name'] == $command->getName()) {
165                     $examples = $item['examples'];
166                     break;
167                 }
168             }
169         }
170
171         $command->getSynopsis(true);
172         $command->getSynopsis(false);
173         $command->mergeApplicationDefinition(false);
174
175         $this->writeText($command->trans('commands.list.messages.usage'), $options);
176         foreach (array_merge([$command->getSynopsis(true)], $command->getAliases(), $command->getUsages()) as $key => $usage) {
177             if ($key > 0) {
178                 $this->writeText("\n");
179             }
180             $this->writeText('  '.$usage, $options);
181         }
182
183         $this->writeText("\n");
184         $definition = $command->getNativeDefinition();
185         if ($definition->getOptions() || $definition->getArguments()) {
186             $this->writeText("\n");
187             $options =
188                 array_merge(
189                     $options,
190                     [ 'command' => $command ]
191                 );
192             $this->describeInputDefinition($definition, $options);
193             $this->writeText("\n");
194         }
195
196         if ($examples) {
197             $this->writeText("\n");
198             $this->writeText("<comment>Examples:</comment>", $options);
199             foreach ($examples as $key => $example) {
200                 $this->writeText("\n");
201                 if ($key != 0) {
202                     $this->writeText("\n");
203                 }
204                 $this->writeText('  <info>'.$example['description'].'</info>');
205                 $this->writeText("\n");
206                 $this->writeText('  '.$example['execution']);
207             }
208         }
209
210         if ($help = $command->getProcessedHelp()) {
211             $this->writeText("\n");
212             $this->writeText($command->trans('commands.list.messages.help'), $options);
213             $this->writeText("\n");
214             $this->writeText(' '.str_replace("\n", "\n ", $help), $options);
215             $this->writeText("\n");
216         }
217     }
218     /**
219      * {@inheritdoc}
220      */
221     protected function describeApplication(Application $application, array $options = [])
222     {
223         $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
224         $description = new ApplicationDescription($application, $describedNamespace);
225         if (isset($options['raw_text']) && $options['raw_text']) {
226             $width = $this->getColumnWidth($description->getCommands());
227             foreach ($description->getCommands() as $command) {
228                 $this->writeText(sprintf("%-${width}s %s", $command->getName(), $command->getDescription()), $options);
229                 $this->writeText("\n");
230             }
231         } else {
232             if ('' != $help = $application->getHelp()) {
233                 $this->writeText("$help\n\n", $options);
234             }
235             if (empty($describedNamespace)) {
236                 $this->writeText(
237                     $application->trans('commands.list.messages.usage'),
238                     $options
239                 );
240                 $this->writeText(
241                     $application->trans(
242                         'commands.list.messages.usage-details'
243                     ),
244                     $options
245                 );
246                 $options['application'] = $application;
247
248                 $this->describeInputDefinition(
249                     new InputDefinition(
250                         $application->getDefinition()->getOptions()
251                     ),
252                     $options
253                 );
254                 $this->writeText("\n");
255                 $this->writeText("\n");
256             }
257
258             $width = $this->getColumnWidth($description->getCommands()) + 4;
259             if ($describedNamespace) {
260                 $this->writeText(sprintf($application->trans('commands.list.messages.comment'), $describedNamespace), $options);
261             } else {
262                 $this->writeText($application->trans('commands.list.messages.available-commands'), $options);
263             }
264
265             $singleCommands = [
266                 'about',
267                 'chain',
268                 'check',
269                 'composerize',
270                 'exec',
271                 'help',
272                 'init',
273                 'list',
274                 'shell',
275                 'server'
276             ];
277
278             // add commands by namespace
279             foreach ($description->getNamespaces() as $namespace) {
280                 if (!$describedNamespace && ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
281                     $this->writeText("\n");
282                     $this->writeText(' <comment>'.$namespace['id'].'</comment>', $options);
283                 }
284                 foreach ($namespace['commands'] as $name) {
285                     if (ApplicationDescription::GLOBAL_NAMESPACE == $namespace['id']) {
286                         if (!in_array($name, $singleCommands)) {
287                             continue;
288                         }
289                     }
290
291                     $this->writeText("\n");
292                     $alias = '';
293                     if ($description->getCommand($name)->getAliases()) {
294                         $alias = sprintf(
295                             '(%s)',
296                             implode(',', $description->getCommand($name)->getAliases())
297                         );
298                     }
299
300                     $spacingWidth = $width - strlen($name.$alias);
301                     if ($spacingWidth < 0) {
302                         $spacingWidth = 0;
303                     }
304
305                     $this->writeText(
306                         sprintf(
307                             '  <info>%s</info> <comment>%s</comment> %s%s',
308                             $name,
309                             $alias,
310                             str_repeat(' ', $spacingWidth),
311                             $description->getCommand($name)->getDescription(
312                             )
313                         ),
314                         $options
315                     );
316                 }
317             }
318             $this->writeText("\n");
319         }
320     }
321     /**
322      * {@inheritdoc}
323      */
324     private function writeText($content, array $options = [])
325     {
326         $this->write(
327             isset($options['raw_text']) && $options['raw_text'] ? strip_tags($content) : $content,
328             isset($options['raw_output']) ? !$options['raw_output'] : true
329         );
330     }
331     /**
332      * Formats input option/argument default value.
333      *
334      * @param mixed $default
335      *
336      * @return string
337      */
338     private function formatDefaultValue($default)
339     {
340         if (PHP_VERSION_ID < 50400) {
341             return str_replace('\/', '/', json_encode($default));
342         }
343         return json_encode($default, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
344     }
345     /**
346      * @param Command[] $commands
347      *
348      * @return int
349      */
350     private function getColumnWidth(array $commands)
351     {
352         $width = 0;
353         foreach ($commands as $command) {
354             $width = strlen($command->getName()) > $width ? strlen($command->getName()) : $width;
355         }
356         return $width + 2;
357     }
358     /**
359      * @param InputOption[] $options
360      *
361      * @return int
362      */
363     private function calculateTotalWidthForOptions($options)
364     {
365         $totalWidth = 0;
366         foreach ($options as $option) {
367             // "-" + shortcut + ", --" + name
368             $nameLength = 1 + max(strlen($option->getShortcut()), 1) + 4 + strlen($option->getName());
369             if ($option->acceptValue()) {
370                 $valueLength = 1 + strlen($option->getName()); // = + value
371                 $valueLength += $option->isValueOptional() ? 2 : 0; // [ + ]
372                 $nameLength += $valueLength;
373             }
374             $totalWidth = max($totalWidth, $nameLength);
375         }
376         return $totalWidth;
377     }
378 }