diff options
Diffstat (limited to 'vendor/symfony/console/Input/InputOption.php')
| -rw-r--r-- | vendor/symfony/console/Input/InputOption.php | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/vendor/symfony/console/Input/InputOption.php b/vendor/symfony/console/Input/InputOption.php new file mode 100644 index 0000000..617c348 --- /dev/null +++ b/vendor/symfony/console/Input/InputOption.php | |||
| @@ -0,0 +1,262 @@ | |||
| 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\Input; | ||
| 13 | |||
| 14 | use Symfony\Component\Console\Command\Command; | ||
| 15 | use Symfony\Component\Console\Completion\CompletionInput; | ||
| 16 | use Symfony\Component\Console\Completion\CompletionSuggestions; | ||
| 17 | use Symfony\Component\Console\Completion\Suggestion; | ||
| 18 | use Symfony\Component\Console\Exception\InvalidArgumentException; | ||
| 19 | use Symfony\Component\Console\Exception\LogicException; | ||
| 20 | |||
| 21 | /** | ||
| 22 | * Represents a command line option. | ||
| 23 | * | ||
| 24 | * @author Fabien Potencier <fabien@symfony.com> | ||
| 25 | */ | ||
| 26 | class InputOption | ||
| 27 | { | ||
| 28 | /** | ||
| 29 | * Do not accept input for the option (e.g. --yell). This is the default behavior of options. | ||
| 30 | */ | ||
| 31 | public const VALUE_NONE = 1; | ||
| 32 | |||
| 33 | /** | ||
| 34 | * A value must be passed when the option is used (e.g. --iterations=5 or -i5). | ||
| 35 | */ | ||
| 36 | public const VALUE_REQUIRED = 2; | ||
| 37 | |||
| 38 | /** | ||
| 39 | * The option may or may not have a value (e.g. --yell or --yell=loud). | ||
| 40 | */ | ||
| 41 | public const VALUE_OPTIONAL = 4; | ||
| 42 | |||
| 43 | /** | ||
| 44 | * The option accepts multiple values (e.g. --dir=/foo --dir=/bar). | ||
| 45 | */ | ||
| 46 | public const VALUE_IS_ARRAY = 8; | ||
| 47 | |||
| 48 | /** | ||
| 49 | * The option allows passing a negated variant (e.g. --ansi or --no-ansi). | ||
| 50 | */ | ||
| 51 | public const VALUE_NEGATABLE = 16; | ||
| 52 | |||
| 53 | private string $name; | ||
| 54 | private ?string $shortcut; | ||
| 55 | private int $mode; | ||
| 56 | private string|int|bool|array|float|null $default; | ||
| 57 | |||
| 58 | /** | ||
| 59 | * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts | ||
| 60 | * @param int-mask-of<InputOption::*>|null $mode The option mode: One of the VALUE_* constants | ||
| 61 | * @param string|bool|int|float|array|null $default The default value (must be null for self::VALUE_NONE) | ||
| 62 | * @param array|\Closure(CompletionInput,CompletionSuggestions):list<string|Suggestion> $suggestedValues The values used for input completion | ||
| 63 | * | ||
| 64 | * @throws InvalidArgumentException If option mode is invalid or incompatible | ||
| 65 | */ | ||
| 66 | public function __construct( | ||
| 67 | string $name, | ||
| 68 | string|array|null $shortcut = null, | ||
| 69 | ?int $mode = null, | ||
| 70 | private string $description = '', | ||
| 71 | string|bool|int|float|array|null $default = null, | ||
| 72 | private array|\Closure $suggestedValues = [], | ||
| 73 | ) { | ||
| 74 | if (str_starts_with($name, '--')) { | ||
| 75 | $name = substr($name, 2); | ||
| 76 | } | ||
| 77 | |||
| 78 | if (!$name) { | ||
| 79 | throw new InvalidArgumentException('An option name cannot be empty.'); | ||
| 80 | } | ||
| 81 | |||
| 82 | if ('' === $shortcut || [] === $shortcut || false === $shortcut) { | ||
| 83 | $shortcut = null; | ||
| 84 | } | ||
| 85 | |||
| 86 | if (null !== $shortcut) { | ||
| 87 | if (\is_array($shortcut)) { | ||
| 88 | $shortcut = implode('|', $shortcut); | ||
| 89 | } | ||
| 90 | $shortcuts = preg_split('{(\|)-?}', ltrim($shortcut, '-')); | ||
| 91 | $shortcuts = array_filter($shortcuts, 'strlen'); | ||
| 92 | $shortcut = implode('|', $shortcuts); | ||
| 93 | |||
| 94 | if ('' === $shortcut) { | ||
| 95 | throw new InvalidArgumentException('An option shortcut cannot be empty.'); | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 99 | if (null === $mode) { | ||
| 100 | $mode = self::VALUE_NONE; | ||
| 101 | } elseif ($mode >= (self::VALUE_NEGATABLE << 1) || $mode < 1) { | ||
| 102 | throw new InvalidArgumentException(sprintf('Option mode "%s" is not valid.', $mode)); | ||
| 103 | } | ||
| 104 | |||
| 105 | $this->name = $name; | ||
| 106 | $this->shortcut = $shortcut; | ||
| 107 | $this->mode = $mode; | ||
| 108 | |||
| 109 | if ($suggestedValues && !$this->acceptValue()) { | ||
| 110 | throw new LogicException('Cannot set suggested values if the option does not accept a value.'); | ||
| 111 | } | ||
| 112 | if ($this->isArray() && !$this->acceptValue()) { | ||
| 113 | throw new InvalidArgumentException('Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.'); | ||
| 114 | } | ||
| 115 | if ($this->isNegatable() && $this->acceptValue()) { | ||
| 116 | throw new InvalidArgumentException('Impossible to have an option mode VALUE_NEGATABLE if the option also accepts a value.'); | ||
| 117 | } | ||
| 118 | |||
| 119 | $this->setDefault($default); | ||
| 120 | } | ||
| 121 | |||
| 122 | /** | ||
| 123 | * Returns the option shortcut. | ||
| 124 | */ | ||
| 125 | public function getShortcut(): ?string | ||
| 126 | { | ||
| 127 | return $this->shortcut; | ||
| 128 | } | ||
| 129 | |||
| 130 | /** | ||
| 131 | * Returns the option name. | ||
| 132 | */ | ||
| 133 | public function getName(): string | ||
| 134 | { | ||
| 135 | return $this->name; | ||
| 136 | } | ||
| 137 | |||
| 138 | /** | ||
| 139 | * Returns true if the option accepts a value. | ||
| 140 | * | ||
| 141 | * @return bool true if value mode is not self::VALUE_NONE, false otherwise | ||
| 142 | */ | ||
| 143 | public function acceptValue(): bool | ||
| 144 | { | ||
| 145 | return $this->isValueRequired() || $this->isValueOptional(); | ||
| 146 | } | ||
| 147 | |||
| 148 | /** | ||
| 149 | * Returns true if the option requires a value. | ||
| 150 | * | ||
| 151 | * @return bool true if value mode is self::VALUE_REQUIRED, false otherwise | ||
| 152 | */ | ||
| 153 | public function isValueRequired(): bool | ||
| 154 | { | ||
| 155 | return self::VALUE_REQUIRED === (self::VALUE_REQUIRED & $this->mode); | ||
| 156 | } | ||
| 157 | |||
| 158 | /** | ||
| 159 | * Returns true if the option takes an optional value. | ||
| 160 | * | ||
| 161 | * @return bool true if value mode is self::VALUE_OPTIONAL, false otherwise | ||
| 162 | */ | ||
| 163 | public function isValueOptional(): bool | ||
| 164 | { | ||
| 165 | return self::VALUE_OPTIONAL === (self::VALUE_OPTIONAL & $this->mode); | ||
| 166 | } | ||
| 167 | |||
| 168 | /** | ||
| 169 | * Returns true if the option can take multiple values. | ||
| 170 | * | ||
| 171 | * @return bool true if mode is self::VALUE_IS_ARRAY, false otherwise | ||
| 172 | */ | ||
| 173 | public function isArray(): bool | ||
| 174 | { | ||
| 175 | return self::VALUE_IS_ARRAY === (self::VALUE_IS_ARRAY & $this->mode); | ||
| 176 | } | ||
| 177 | |||
| 178 | /** | ||
| 179 | * Returns true if the option allows passing a negated variant. | ||
| 180 | * | ||
| 181 | * @return bool true if mode is self::VALUE_NEGATABLE, false otherwise | ||
| 182 | */ | ||
| 183 | public function isNegatable(): bool | ||
| 184 | { | ||
| 185 | return self::VALUE_NEGATABLE === (self::VALUE_NEGATABLE & $this->mode); | ||
| 186 | } | ||
| 187 | |||
| 188 | /** | ||
| 189 | * Sets the default value. | ||
| 190 | */ | ||
| 191 | public function setDefault(string|bool|int|float|array|null $default): void | ||
| 192 | { | ||
| 193 | if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) { | ||
| 194 | throw new LogicException('Cannot set a default value when using InputOption::VALUE_NONE mode.'); | ||
| 195 | } | ||
| 196 | |||
| 197 | if ($this->isArray()) { | ||
| 198 | if (null === $default) { | ||
| 199 | $default = []; | ||
| 200 | } elseif (!\is_array($default)) { | ||
| 201 | throw new LogicException('A default value for an array option must be an array.'); | ||
| 202 | } | ||
| 203 | } | ||
| 204 | |||
| 205 | $this->default = $this->acceptValue() || $this->isNegatable() ? $default : false; | ||
| 206 | } | ||
| 207 | |||
| 208 | /** | ||
| 209 | * Returns the default value. | ||
| 210 | */ | ||
| 211 | public function getDefault(): string|bool|int|float|array|null | ||
| 212 | { | ||
| 213 | return $this->default; | ||
| 214 | } | ||
| 215 | |||
| 216 | /** | ||
| 217 | * Returns the description text. | ||
| 218 | */ | ||
| 219 | public function getDescription(): string | ||
| 220 | { | ||
| 221 | return $this->description; | ||
| 222 | } | ||
| 223 | |||
| 224 | /** | ||
| 225 | * Returns true if the option has values for input completion. | ||
| 226 | */ | ||
| 227 | public function hasCompletion(): bool | ||
| 228 | { | ||
| 229 | return [] !== $this->suggestedValues; | ||
| 230 | } | ||
| 231 | |||
| 232 | /** | ||
| 233 | * Supplies suggestions when command resolves possible completion options for input. | ||
| 234 | * | ||
| 235 | * @see Command::complete() | ||
| 236 | */ | ||
| 237 | public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void | ||
| 238 | { | ||
| 239 | $values = $this->suggestedValues; | ||
| 240 | if ($values instanceof \Closure && !\is_array($values = $values($input))) { | ||
| 241 | throw new LogicException(sprintf('Closure for option "%s" must return an array. Got "%s".', $this->name, get_debug_type($values))); | ||
| 242 | } | ||
| 243 | if ($values) { | ||
| 244 | $suggestions->suggestValues($values); | ||
| 245 | } | ||
| 246 | } | ||
| 247 | |||
| 248 | /** | ||
| 249 | * Checks whether the given option equals this one. | ||
| 250 | */ | ||
| 251 | public function equals(self $option): bool | ||
| 252 | { | ||
| 253 | return $option->getName() === $this->getName() | ||
| 254 | && $option->getShortcut() === $this->getShortcut() | ||
| 255 | && $option->getDefault() === $this->getDefault() | ||
| 256 | && $option->isNegatable() === $this->isNegatable() | ||
| 257 | && $option->isArray() === $this->isArray() | ||
| 258 | && $option->isValueRequired() === $this->isValueRequired() | ||
| 259 | && $option->isValueOptional() === $this->isValueOptional() | ||
| 260 | ; | ||
| 261 | } | ||
| 262 | } | ||
