annotate vendor/psy/psysh/src/Command/Command.php @ 19:fa3358dc1485 tip

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