summaryrefslogtreecommitdiff
path: root/vendor/symfony/console/Input
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/symfony/console/Input')
-rw-r--r--vendor/symfony/console/Input/ArgvInput.php396
-rw-r--r--vendor/symfony/console/Input/ArrayInput.php191
-rw-r--r--vendor/symfony/console/Input/Input.php174
-rw-r--r--vendor/symfony/console/Input/InputArgument.php160
-rw-r--r--vendor/symfony/console/Input/InputAwareInterface.php26
-rw-r--r--vendor/symfony/console/Input/InputDefinition.php402
-rw-r--r--vendor/symfony/console/Input/InputInterface.php138
-rw-r--r--vendor/symfony/console/Input/InputOption.php262
-rw-r--r--vendor/symfony/console/Input/StreamableInputInterface.php37
-rw-r--r--vendor/symfony/console/Input/StringInput.php85
10 files changed, 1871 insertions, 0 deletions
diff --git a/vendor/symfony/console/Input/ArgvInput.php b/vendor/symfony/console/Input/ArgvInput.php
new file mode 100644
index 0000000..95703ba
--- /dev/null
+++ b/vendor/symfony/console/Input/ArgvInput.php
@@ -0,0 +1,396 @@
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
12namespace Symfony\Component\Console\Input;
13
14use Symfony\Component\Console\Exception\RuntimeException;
15
16/**
17 * ArgvInput represents an input coming from the CLI arguments.
18 *
19 * Usage:
20 *
21 * $input = new ArgvInput();
22 *
23 * By default, the `$_SERVER['argv']` array is used for the input values.
24 *
25 * This can be overridden by explicitly passing the input values in the constructor:
26 *
27 * $input = new ArgvInput($_SERVER['argv']);
28 *
29 * If you pass it yourself, don't forget that the first element of the array
30 * is the name of the running application.
31 *
32 * When passing an argument to the constructor, be sure that it respects
33 * the same rules as the argv one. It's almost always better to use the
34 * `StringInput` when you want to provide your own input.
35 *
36 * @author Fabien Potencier <fabien@symfony.com>
37 *
38 * @see http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
39 * @see http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02
40 */
41class ArgvInput extends Input
42{
43 /** @var list<string> */
44 private array $tokens;
45 private array $parsed;
46
47 /** @param list<string>|null $argv */
48 public function __construct(?array $argv = null, ?InputDefinition $definition = null)
49 {
50 $argv ??= $_SERVER['argv'] ?? [];
51
52 // strip the application name
53 array_shift($argv);
54
55 $this->tokens = $argv;
56
57 parent::__construct($definition);
58 }
59
60 /** @param list<string> $tokens */
61 protected function setTokens(array $tokens): void
62 {
63 $this->tokens = $tokens;
64 }
65
66 protected function parse(): void
67 {
68 $parseOptions = true;
69 $this->parsed = $this->tokens;
70 while (null !== $token = array_shift($this->parsed)) {
71 $parseOptions = $this->parseToken($token, $parseOptions);
72 }
73 }
74
75 protected function parseToken(string $token, bool $parseOptions): bool
76 {
77 if ($parseOptions && '' == $token) {
78 $this->parseArgument($token);
79 } elseif ($parseOptions && '--' == $token) {
80 return false;
81 } elseif ($parseOptions && str_starts_with($token, '--')) {
82 $this->parseLongOption($token);
83 } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) {
84 $this->parseShortOption($token);
85 } else {
86 $this->parseArgument($token);
87 }
88
89 return $parseOptions;
90 }
91
92 /**
93 * Parses a short option.
94 */
95 private function parseShortOption(string $token): void
96 {
97 $name = substr($token, 1);
98
99 if (\strlen($name) > 1) {
100 if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) {
101 // an option with a value (with no space)
102 $this->addShortOption($name[0], substr($name, 1));
103 } else {
104 $this->parseShortOptionSet($name);
105 }
106 } else {
107 $this->addShortOption($name, null);
108 }
109 }
110
111 /**
112 * Parses a short option set.
113 *
114 * @throws RuntimeException When option given doesn't exist
115 */
116 private function parseShortOptionSet(string $name): void
117 {
118 $len = \strlen($name);
119 for ($i = 0; $i < $len; ++$i) {
120 if (!$this->definition->hasShortcut($name[$i])) {
121 $encoding = mb_detect_encoding($name, null, true);
122 throw new RuntimeException(sprintf('The "-%s" option does not exist.', false === $encoding ? $name[$i] : mb_substr($name, $i, 1, $encoding)));
123 }
124
125 $option = $this->definition->getOptionForShortcut($name[$i]);
126 if ($option->acceptValue()) {
127 $this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1));
128
129 break;
130 } else {
131 $this->addLongOption($option->getName(), null);
132 }
133 }
134 }
135
136 /**
137 * Parses a long option.
138 */
139 private function parseLongOption(string $token): void
140 {
141 $name = substr($token, 2);
142
143 if (false !== $pos = strpos($name, '=')) {
144 if ('' === $value = substr($name, $pos + 1)) {
145 array_unshift($this->parsed, $value);
146 }
147 $this->addLongOption(substr($name, 0, $pos), $value);
148 } else {
149 $this->addLongOption($name, null);
150 }
151 }
152
153 /**
154 * Parses an argument.
155 *
156 * @throws RuntimeException When too many arguments are given
157 */
158 private function parseArgument(string $token): void
159 {
160 $c = \count($this->arguments);
161
162 // if input is expecting another argument, add it
163 if ($this->definition->hasArgument($c)) {
164 $arg = $this->definition->getArgument($c);
165 $this->arguments[$arg->getName()] = $arg->isArray() ? [$token] : $token;
166
167 // if last argument isArray(), append token to last argument
168 } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) {
169 $arg = $this->definition->getArgument($c - 1);
170 $this->arguments[$arg->getName()][] = $token;
171
172 // unexpected argument
173 } else {
174 $all = $this->definition->getArguments();
175 $symfonyCommandName = null;
176 if (($inputArgument = $all[$key = array_key_first($all)] ?? null) && 'command' === $inputArgument->getName()) {
177 $symfonyCommandName = $this->arguments['command'] ?? null;
178 unset($all[$key]);
179 }
180
181 if (\count($all)) {
182 if ($symfonyCommandName) {
183 $message = sprintf('Too many arguments to "%s" command, expected arguments "%s".', $symfonyCommandName, implode('" "', array_keys($all)));
184 } else {
185 $message = sprintf('Too many arguments, expected arguments "%s".', implode('" "', array_keys($all)));
186 }
187 } elseif ($symfonyCommandName) {
188 $message = sprintf('No arguments expected for "%s" command, got "%s".', $symfonyCommandName, $token);
189 } else {
190 $message = sprintf('No arguments expected, got "%s".', $token);
191 }
192
193 throw new RuntimeException($message);
194 }
195 }
196
197 /**
198 * Adds a short option value.
199 *
200 * @throws RuntimeException When option given doesn't exist
201 */
202 private function addShortOption(string $shortcut, mixed $value): void
203 {
204 if (!$this->definition->hasShortcut($shortcut)) {
205 throw new RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut));
206 }
207
208 $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
209 }
210
211 /**
212 * Adds a long option value.
213 *
214 * @throws RuntimeException When option given doesn't exist
215 */
216 private function addLongOption(string $name, mixed $value): void
217 {
218 if (!$this->definition->hasOption($name)) {
219 if (!$this->definition->hasNegation($name)) {
220 throw new RuntimeException(sprintf('The "--%s" option does not exist.', $name));
221 }
222
223 $optionName = $this->definition->negationToName($name);
224 if (null !== $value) {
225 throw new RuntimeException(sprintf('The "--%s" option does not accept a value.', $name));
226 }
227 $this->options[$optionName] = false;
228
229 return;
230 }
231
232 $option = $this->definition->getOption($name);
233
234 if (null !== $value && !$option->acceptValue()) {
235 throw new RuntimeException(sprintf('The "--%s" option does not accept a value.', $name));
236 }
237
238 if (\in_array($value, ['', null], true) && $option->acceptValue() && \count($this->parsed)) {
239 // if option accepts an optional or mandatory argument
240 // let's see if there is one provided
241 $next = array_shift($this->parsed);
242 if ((isset($next[0]) && '-' !== $next[0]) || \in_array($next, ['', null], true)) {
243 $value = $next;
244 } else {
245 array_unshift($this->parsed, $next);
246 }
247 }
248
249 if (null === $value) {
250 if ($option->isValueRequired()) {
251 throw new RuntimeException(sprintf('The "--%s" option requires a value.', $name));
252 }
253
254 if (!$option->isArray() && !$option->isValueOptional()) {
255 $value = true;
256 }
257 }
258
259 if ($option->isArray()) {
260 $this->options[$name][] = $value;
261 } else {
262 $this->options[$name] = $value;
263 }
264 }
265
266 public function getFirstArgument(): ?string
267 {
268 $isOption = false;
269 foreach ($this->tokens as $i => $token) {
270 if ($token && '-' === $token[0]) {
271 if (str_contains($token, '=') || !isset($this->tokens[$i + 1])) {
272 continue;
273 }
274
275 // If it's a long option, consider that everything after "--" is the option name.
276 // Otherwise, use the last char (if it's a short option set, only the last one can take a value with space separator)
277 $name = '-' === $token[1] ? substr($token, 2) : substr($token, -1);
278 if (!isset($this->options[$name]) && !$this->definition->hasShortcut($name)) {
279 // noop
280 } elseif ((isset($this->options[$name]) || isset($this->options[$name = $this->definition->shortcutToName($name)])) && $this->tokens[$i + 1] === $this->options[$name]) {
281 $isOption = true;
282 }
283
284 continue;
285 }
286
287 if ($isOption) {
288 $isOption = false;
289 continue;
290 }
291
292 return $token;
293 }
294
295 return null;
296 }
297
298 public function hasParameterOption(string|array $values, bool $onlyParams = false): bool
299 {
300 $values = (array) $values;
301
302 foreach ($this->tokens as $token) {
303 if ($onlyParams && '--' === $token) {
304 return false;
305 }
306 foreach ($values as $value) {
307 // Options with values:
308 // For long options, test for '--option=' at beginning
309 // For short options, test for '-o' at beginning
310 $leading = str_starts_with($value, '--') ? $value.'=' : $value;
311 if ($token === $value || '' !== $leading && str_starts_with($token, $leading)) {
312 return true;
313 }
314 }
315 }
316
317 return false;
318 }
319
320 public function getParameterOption(string|array $values, string|bool|int|float|array|null $default = false, bool $onlyParams = false): mixed
321 {
322 $values = (array) $values;
323 $tokens = $this->tokens;
324
325 while (0 < \count($tokens)) {
326 $token = array_shift($tokens);
327 if ($onlyParams && '--' === $token) {
328 return $default;
329 }
330
331 foreach ($values as $value) {
332 if ($token === $value) {
333 return array_shift($tokens);
334 }
335 // Options with values:
336 // For long options, test for '--option=' at beginning
337 // For short options, test for '-o' at beginning
338 $leading = str_starts_with($value, '--') ? $value.'=' : $value;
339 if ('' !== $leading && str_starts_with($token, $leading)) {
340 return substr($token, \strlen($leading));
341 }
342 }
343 }
344
345 return $default;
346 }
347
348 /**
349 * Returns un-parsed and not validated tokens.
350 *
351 * @param bool $strip Whether to return the raw parameters (false) or the values after the command name (true)
352 *
353 * @return list<string>
354 */
355 public function getRawTokens(bool $strip = false): array
356 {
357 if (!$strip) {
358 return $this->tokens;
359 }
360
361 $parameters = [];
362 $keep = false;
363 foreach ($this->tokens as $value) {
364 if (!$keep && $value === $this->getFirstArgument()) {
365 $keep = true;
366
367 continue;
368 }
369 if ($keep) {
370 $parameters[] = $value;
371 }
372 }
373
374 return $parameters;
375 }
376
377 /**
378 * Returns a stringified representation of the args passed to the command.
379 */
380 public function __toString(): string
381 {
382 $tokens = array_map(function ($token) {
383 if (preg_match('{^(-[^=]+=)(.+)}', $token, $match)) {
384 return $match[1].$this->escapeToken($match[2]);
385 }
386
387 if ($token && '-' !== $token[0]) {
388 return $this->escapeToken($token);
389 }
390
391 return $token;
392 }, $this->tokens);
393
394 return implode(' ', $tokens);
395 }
396}
diff --git a/vendor/symfony/console/Input/ArrayInput.php b/vendor/symfony/console/Input/ArrayInput.php
new file mode 100644
index 0000000..d27ff41
--- /dev/null
+++ b/vendor/symfony/console/Input/ArrayInput.php
@@ -0,0 +1,191 @@
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
12namespace Symfony\Component\Console\Input;
13
14use Symfony\Component\Console\Exception\InvalidArgumentException;
15use Symfony\Component\Console\Exception\InvalidOptionException;
16
17/**
18 * ArrayInput represents an input provided as an array.
19 *
20 * Usage:
21 *
22 * $input = new ArrayInput(['command' => 'foo:bar', 'foo' => 'bar', '--bar' => 'foobar']);
23 *
24 * @author Fabien Potencier <fabien@symfony.com>
25 */
26class ArrayInput extends Input
27{
28 public function __construct(
29 private array $parameters,
30 ?InputDefinition $definition = null,
31 ) {
32 parent::__construct($definition);
33 }
34
35 public function getFirstArgument(): ?string
36 {
37 foreach ($this->parameters as $param => $value) {
38 if ($param && \is_string($param) && '-' === $param[0]) {
39 continue;
40 }
41
42 return $value;
43 }
44
45 return null;
46 }
47
48 public function hasParameterOption(string|array $values, bool $onlyParams = false): bool
49 {
50 $values = (array) $values;
51
52 foreach ($this->parameters as $k => $v) {
53 if (!\is_int($k)) {
54 $v = $k;
55 }
56
57 if ($onlyParams && '--' === $v) {
58 return false;
59 }
60
61 if (\in_array($v, $values)) {
62 return true;
63 }
64 }
65
66 return false;
67 }
68
69 public function getParameterOption(string|array $values, string|bool|int|float|array|null $default = false, bool $onlyParams = false): mixed
70 {
71 $values = (array) $values;
72
73 foreach ($this->parameters as $k => $v) {
74 if ($onlyParams && ('--' === $k || (\is_int($k) && '--' === $v))) {
75 return $default;
76 }
77
78 if (\is_int($k)) {
79 if (\in_array($v, $values)) {
80 return true;
81 }
82 } elseif (\in_array($k, $values)) {
83 return $v;
84 }
85 }
86
87 return $default;
88 }
89
90 /**
91 * Returns a stringified representation of the args passed to the command.
92 */
93 public function __toString(): string
94 {
95 $params = [];
96 foreach ($this->parameters as $param => $val) {
97 if ($param && \is_string($param) && '-' === $param[0]) {
98 $glue = ('-' === $param[1]) ? '=' : ' ';
99 if (\is_array($val)) {
100 foreach ($val as $v) {
101 $params[] = $param.('' != $v ? $glue.$this->escapeToken($v) : '');
102 }
103 } else {
104 $params[] = $param.('' != $val ? $glue.$this->escapeToken($val) : '');
105 }
106 } else {
107 $params[] = \is_array($val) ? implode(' ', array_map($this->escapeToken(...), $val)) : $this->escapeToken($val);
108 }
109 }
110
111 return implode(' ', $params);
112 }
113
114 protected function parse(): void
115 {
116 foreach ($this->parameters as $key => $value) {
117 if ('--' === $key) {
118 return;
119 }
120 if (str_starts_with($key, '--')) {
121 $this->addLongOption(substr($key, 2), $value);
122 } elseif (str_starts_with($key, '-')) {
123 $this->addShortOption(substr($key, 1), $value);
124 } else {
125 $this->addArgument($key, $value);
126 }
127 }
128 }
129
130 /**
131 * Adds a short option value.
132 *
133 * @throws InvalidOptionException When option given doesn't exist
134 */
135 private function addShortOption(string $shortcut, mixed $value): void
136 {
137 if (!$this->definition->hasShortcut($shortcut)) {
138 throw new InvalidOptionException(sprintf('The "-%s" option does not exist.', $shortcut));
139 }
140
141 $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
142 }
143
144 /**
145 * Adds a long option value.
146 *
147 * @throws InvalidOptionException When option given doesn't exist
148 * @throws InvalidOptionException When a required value is missing
149 */
150 private function addLongOption(string $name, mixed $value): void
151 {
152 if (!$this->definition->hasOption($name)) {
153 if (!$this->definition->hasNegation($name)) {
154 throw new InvalidOptionException(sprintf('The "--%s" option does not exist.', $name));
155 }
156
157 $optionName = $this->definition->negationToName($name);
158 $this->options[$optionName] = false;
159
160 return;
161 }
162
163 $option = $this->definition->getOption($name);
164
165 if (null === $value) {
166 if ($option->isValueRequired()) {
167 throw new InvalidOptionException(sprintf('The "--%s" option requires a value.', $name));
168 }
169
170 if (!$option->isValueOptional()) {
171 $value = true;
172 }
173 }
174
175 $this->options[$name] = $value;
176 }
177
178 /**
179 * Adds an argument value.
180 *
181 * @throws InvalidArgumentException When argument given doesn't exist
182 */
183 private function addArgument(string|int $name, mixed $value): void
184 {
185 if (!$this->definition->hasArgument($name)) {
186 throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
187 }
188
189 $this->arguments[$name] = $value;
190 }
191}
diff --git a/vendor/symfony/console/Input/Input.php b/vendor/symfony/console/Input/Input.php
new file mode 100644
index 0000000..5a8b9a2
--- /dev/null
+++ b/vendor/symfony/console/Input/Input.php
@@ -0,0 +1,174 @@
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
12namespace Symfony\Component\Console\Input;
13
14use Symfony\Component\Console\Exception\InvalidArgumentException;
15use Symfony\Component\Console\Exception\RuntimeException;
16
17/**
18 * Input is the base class for all concrete Input classes.
19 *
20 * Three concrete classes are provided by default:
21 *
22 * * `ArgvInput`: The input comes from the CLI arguments (argv)
23 * * `StringInput`: The input is provided as a string
24 * * `ArrayInput`: The input is provided as an array
25 *
26 * @author Fabien Potencier <fabien@symfony.com>
27 */
28abstract class Input implements InputInterface, StreamableInputInterface
29{
30 protected InputDefinition $definition;
31 /** @var resource */
32 protected $stream;
33 protected array $options = [];
34 protected array $arguments = [];
35 protected bool $interactive = true;
36
37 public function __construct(?InputDefinition $definition = null)
38 {
39 if (null === $definition) {
40 $this->definition = new InputDefinition();
41 } else {
42 $this->bind($definition);
43 $this->validate();
44 }
45 }
46
47 public function bind(InputDefinition $definition): void
48 {
49 $this->arguments = [];
50 $this->options = [];
51 $this->definition = $definition;
52
53 $this->parse();
54 }
55
56 /**
57 * Processes command line arguments.
58 */
59 abstract protected function parse(): void;
60
61 public function validate(): void
62 {
63 $definition = $this->definition;
64 $givenArguments = $this->arguments;
65
66 $missingArguments = array_filter(array_keys($definition->getArguments()), fn ($argument) => !\array_key_exists($argument, $givenArguments) && $definition->getArgument($argument)->isRequired());
67
68 if (\count($missingArguments) > 0) {
69 throw new RuntimeException(sprintf('Not enough arguments (missing: "%s").', implode(', ', $missingArguments)));
70 }
71 }
72
73 public function isInteractive(): bool
74 {
75 return $this->interactive;
76 }
77
78 public function setInteractive(bool $interactive): void
79 {
80 $this->interactive = $interactive;
81 }
82
83 public function getArguments(): array
84 {
85 return array_merge($this->definition->getArgumentDefaults(), $this->arguments);
86 }
87
88 public function getArgument(string $name): mixed
89 {
90 if (!$this->definition->hasArgument($name)) {
91 throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
92 }
93
94 return $this->arguments[$name] ?? $this->definition->getArgument($name)->getDefault();
95 }
96
97 public function setArgument(string $name, mixed $value): void
98 {
99 if (!$this->definition->hasArgument($name)) {
100 throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
101 }
102
103 $this->arguments[$name] = $value;
104 }
105
106 public function hasArgument(string $name): bool
107 {
108 return $this->definition->hasArgument($name);
109 }
110
111 public function getOptions(): array
112 {
113 return array_merge($this->definition->getOptionDefaults(), $this->options);
114 }
115
116 public function getOption(string $name): mixed
117 {
118 if ($this->definition->hasNegation($name)) {
119 if (null === $value = $this->getOption($this->definition->negationToName($name))) {
120 return $value;
121 }
122
123 return !$value;
124 }
125
126 if (!$this->definition->hasOption($name)) {
127 throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
128 }
129
130 return \array_key_exists($name, $this->options) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();
131 }
132
133 public function setOption(string $name, mixed $value): void
134 {
135 if ($this->definition->hasNegation($name)) {
136 $this->options[$this->definition->negationToName($name)] = !$value;
137
138 return;
139 } elseif (!$this->definition->hasOption($name)) {
140 throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
141 }
142
143 $this->options[$name] = $value;
144 }
145
146 public function hasOption(string $name): bool
147 {
148 return $this->definition->hasOption($name) || $this->definition->hasNegation($name);
149 }
150
151 /**
152 * Escapes a token through escapeshellarg if it contains unsafe chars.
153 */
154 public function escapeToken(string $token): string
155 {
156 return preg_match('{^[\w-]+$}', $token) ? $token : escapeshellarg($token);
157 }
158
159 /**
160 * @param resource $stream
161 */
162 public function setStream($stream): void
163 {
164 $this->stream = $stream;
165 }
166
167 /**
168 * @return resource
169 */
170 public function getStream()
171 {
172 return $this->stream;
173 }
174}
diff --git a/vendor/symfony/console/Input/InputArgument.php b/vendor/symfony/console/Input/InputArgument.php
new file mode 100644
index 0000000..a5d9492
--- /dev/null
+++ b/vendor/symfony/console/Input/InputArgument.php
@@ -0,0 +1,160 @@
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
12namespace Symfony\Component\Console\Input;
13
14use Symfony\Component\Console\Command\Command;
15use Symfony\Component\Console\Completion\CompletionInput;
16use Symfony\Component\Console\Completion\CompletionSuggestions;
17use Symfony\Component\Console\Completion\Suggestion;
18use Symfony\Component\Console\Exception\InvalidArgumentException;
19use Symfony\Component\Console\Exception\LogicException;
20
21/**
22 * Represents a command line argument.
23 *
24 * @author Fabien Potencier <fabien@symfony.com>
25 */
26class InputArgument
27{
28 /**
29 * Providing an argument is required (e.g. just 'app:foo' is not allowed).
30 */
31 public const REQUIRED = 1;
32
33 /**
34 * Providing an argument is optional (e.g. 'app:foo' and 'app:foo bar' are both allowed). This is the default behavior of arguments.
35 */
36 public const OPTIONAL = 2;
37
38 /**
39 * The argument accepts multiple values and turn them into an array (e.g. 'app:foo bar baz' will result in value ['bar', 'baz']).
40 */
41 public const IS_ARRAY = 4;
42
43 private int $mode;
44 private string|int|bool|array|float|null $default;
45
46 /**
47 * @param string $name The argument name
48 * @param int-mask-of<InputArgument::*>|null $mode The argument mode: a bit mask of self::REQUIRED, self::OPTIONAL and self::IS_ARRAY
49 * @param string $description A description text
50 * @param string|bool|int|float|array|null $default The default value (for self::OPTIONAL mode only)
51 * @param array|\Closure(CompletionInput,CompletionSuggestions):list<string|Suggestion> $suggestedValues The values used for input completion
52 *
53 * @throws InvalidArgumentException When argument mode is not valid
54 */
55 public function __construct(
56 private string $name,
57 ?int $mode = null,
58 private string $description = '',
59 string|bool|int|float|array|null $default = null,
60 private \Closure|array $suggestedValues = [],
61 ) {
62 if (null === $mode) {
63 $mode = self::OPTIONAL;
64 } elseif ($mode >= (self::IS_ARRAY << 1) || $mode < 1) {
65 throw new InvalidArgumentException(sprintf('Argument mode "%s" is not valid.', $mode));
66 }
67
68 $this->mode = $mode;
69
70 $this->setDefault($default);
71 }
72
73 /**
74 * Returns the argument name.
75 */
76 public function getName(): string
77 {
78 return $this->name;
79 }
80
81 /**
82 * Returns true if the argument is required.
83 *
84 * @return bool true if parameter mode is self::REQUIRED, false otherwise
85 */
86 public function isRequired(): bool
87 {
88 return self::REQUIRED === (self::REQUIRED & $this->mode);
89 }
90
91 /**
92 * Returns true if the argument can take multiple values.
93 *
94 * @return bool true if mode is self::IS_ARRAY, false otherwise
95 */
96 public function isArray(): bool
97 {
98 return self::IS_ARRAY === (self::IS_ARRAY & $this->mode);
99 }
100
101 /**
102 * Sets the default value.
103 */
104 public function setDefault(string|bool|int|float|array|null $default): void
105 {
106 if ($this->isRequired() && null !== $default) {
107 throw new LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.');
108 }
109
110 if ($this->isArray()) {
111 if (null === $default) {
112 $default = [];
113 } elseif (!\is_array($default)) {
114 throw new LogicException('A default value for an array argument must be an array.');
115 }
116 }
117
118 $this->default = $default;
119 }
120
121 /**
122 * Returns the default value.
123 */
124 public function getDefault(): string|bool|int|float|array|null
125 {
126 return $this->default;
127 }
128
129 /**
130 * Returns true if the argument has values for input completion.
131 */
132 public function hasCompletion(): bool
133 {
134 return [] !== $this->suggestedValues;
135 }
136
137 /**
138 * Supplies suggestions when command resolves possible completion options for input.
139 *
140 * @see Command::complete()
141 */
142 public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
143 {
144 $values = $this->suggestedValues;
145 if ($values instanceof \Closure && !\is_array($values = $values($input))) {
146 throw new LogicException(sprintf('Closure for argument "%s" must return an array. Got "%s".', $this->name, get_debug_type($values)));
147 }
148 if ($values) {
149 $suggestions->suggestValues($values);
150 }
151 }
152
153 /**
154 * Returns the description text.
155 */
156 public function getDescription(): string
157 {
158 return $this->description;
159 }
160}
diff --git a/vendor/symfony/console/Input/InputAwareInterface.php b/vendor/symfony/console/Input/InputAwareInterface.php
new file mode 100644
index 0000000..ba4664c
--- /dev/null
+++ b/vendor/symfony/console/Input/InputAwareInterface.php
@@ -0,0 +1,26 @@
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
12namespace Symfony\Component\Console\Input;
13
14/**
15 * InputAwareInterface should be implemented by classes that depends on the
16 * Console Input.
17 *
18 * @author Wouter J <waldio.webdesign@gmail.com>
19 */
20interface InputAwareInterface
21{
22 /**
23 * Sets the Console Input.
24 */
25 public function setInput(InputInterface $input): void;
26}
diff --git a/vendor/symfony/console/Input/InputDefinition.php b/vendor/symfony/console/Input/InputDefinition.php
new file mode 100644
index 0000000..f27e297
--- /dev/null
+++ b/vendor/symfony/console/Input/InputDefinition.php
@@ -0,0 +1,402 @@
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
12namespace Symfony\Component\Console\Input;
13
14use Symfony\Component\Console\Exception\InvalidArgumentException;
15use Symfony\Component\Console\Exception\LogicException;
16
17/**
18 * A InputDefinition represents a set of valid command line arguments and options.
19 *
20 * Usage:
21 *
22 * $definition = new InputDefinition([
23 * new InputArgument('name', InputArgument::REQUIRED),
24 * new InputOption('foo', 'f', InputOption::VALUE_REQUIRED),
25 * ]);
26 *
27 * @author Fabien Potencier <fabien@symfony.com>
28 */
29class InputDefinition
30{
31 private array $arguments = [];
32 private int $requiredCount = 0;
33 private ?InputArgument $lastArrayArgument = null;
34 private ?InputArgument $lastOptionalArgument = null;
35 private array $options = [];
36 private array $negations = [];
37 private array $shortcuts = [];
38
39 /**
40 * @param array $definition An array of InputArgument and InputOption instance
41 */
42 public function __construct(array $definition = [])
43 {
44 $this->setDefinition($definition);
45 }
46
47 /**
48 * Sets the definition of the input.
49 */
50 public function setDefinition(array $definition): void
51 {
52 $arguments = [];
53 $options = [];
54 foreach ($definition as $item) {
55 if ($item instanceof InputOption) {
56 $options[] = $item;
57 } else {
58 $arguments[] = $item;
59 }
60 }
61
62 $this->setArguments($arguments);
63 $this->setOptions($options);
64 }
65
66 /**
67 * Sets the InputArgument objects.
68 *
69 * @param InputArgument[] $arguments An array of InputArgument objects
70 */
71 public function setArguments(array $arguments = []): void
72 {
73 $this->arguments = [];
74 $this->requiredCount = 0;
75 $this->lastOptionalArgument = null;
76 $this->lastArrayArgument = null;
77 $this->addArguments($arguments);
78 }
79
80 /**
81 * Adds an array of InputArgument objects.
82 *
83 * @param InputArgument[] $arguments An array of InputArgument objects
84 */
85 public function addArguments(?array $arguments = []): void
86 {
87 if (null !== $arguments) {
88 foreach ($arguments as $argument) {
89 $this->addArgument($argument);
90 }
91 }
92 }
93
94 /**
95 * @throws LogicException When incorrect argument is given
96 */
97 public function addArgument(InputArgument $argument): void
98 {
99 if (isset($this->arguments[$argument->getName()])) {
100 throw new LogicException(sprintf('An argument with name "%s" already exists.', $argument->getName()));
101 }
102
103 if (null !== $this->lastArrayArgument) {
104 throw new LogicException(sprintf('Cannot add a required argument "%s" after an array argument "%s".', $argument->getName(), $this->lastArrayArgument->getName()));
105 }
106
107 if ($argument->isRequired() && null !== $this->lastOptionalArgument) {
108 throw new LogicException(sprintf('Cannot add a required argument "%s" after an optional one "%s".', $argument->getName(), $this->lastOptionalArgument->getName()));
109 }
110
111 if ($argument->isArray()) {
112 $this->lastArrayArgument = $argument;
113 }
114
115 if ($argument->isRequired()) {
116 ++$this->requiredCount;
117 } else {
118 $this->lastOptionalArgument = $argument;
119 }
120
121 $this->arguments[$argument->getName()] = $argument;
122 }
123
124 /**
125 * Returns an InputArgument by name or by position.
126 *
127 * @throws InvalidArgumentException When argument given doesn't exist
128 */
129 public function getArgument(string|int $name): InputArgument
130 {
131 if (!$this->hasArgument($name)) {
132 throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
133 }
134
135 $arguments = \is_int($name) ? array_values($this->arguments) : $this->arguments;
136
137 return $arguments[$name];
138 }
139
140 /**
141 * Returns true if an InputArgument object exists by name or position.
142 */
143 public function hasArgument(string|int $name): bool
144 {
145 $arguments = \is_int($name) ? array_values($this->arguments) : $this->arguments;
146
147 return isset($arguments[$name]);
148 }
149
150 /**
151 * Gets the array of InputArgument objects.
152 *
153 * @return InputArgument[]
154 */
155 public function getArguments(): array
156 {
157 return $this->arguments;
158 }
159
160 /**
161 * Returns the number of InputArguments.
162 */
163 public function getArgumentCount(): int
164 {
165 return null !== $this->lastArrayArgument ? \PHP_INT_MAX : \count($this->arguments);
166 }
167
168 /**
169 * Returns the number of required InputArguments.
170 */
171 public function getArgumentRequiredCount(): int
172 {
173 return $this->requiredCount;
174 }
175
176 /**
177 * @return array<string|bool|int|float|array|null>
178 */
179 public function getArgumentDefaults(): array
180 {
181 $values = [];
182 foreach ($this->arguments as $argument) {
183 $values[$argument->getName()] = $argument->getDefault();
184 }
185
186 return $values;
187 }
188
189 /**
190 * Sets the InputOption objects.
191 *
192 * @param InputOption[] $options An array of InputOption objects
193 */
194 public function setOptions(array $options = []): void
195 {
196 $this->options = [];
197 $this->shortcuts = [];
198 $this->negations = [];
199 $this->addOptions($options);
200 }
201
202 /**
203 * Adds an array of InputOption objects.
204 *
205 * @param InputOption[] $options An array of InputOption objects
206 */
207 public function addOptions(array $options = []): void
208 {
209 foreach ($options as $option) {
210 $this->addOption($option);
211 }
212 }
213
214 /**
215 * @throws LogicException When option given already exist
216 */
217 public function addOption(InputOption $option): void
218 {
219 if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) {
220 throw new LogicException(sprintf('An option named "%s" already exists.', $option->getName()));
221 }
222 if (isset($this->negations[$option->getName()])) {
223 throw new LogicException(sprintf('An option named "%s" already exists.', $option->getName()));
224 }
225
226 if ($option->getShortcut()) {
227 foreach (explode('|', $option->getShortcut()) as $shortcut) {
228 if (isset($this->shortcuts[$shortcut]) && !$option->equals($this->options[$this->shortcuts[$shortcut]])) {
229 throw new LogicException(sprintf('An option with shortcut "%s" already exists.', $shortcut));
230 }
231 }
232 }
233
234 $this->options[$option->getName()] = $option;
235 if ($option->getShortcut()) {
236 foreach (explode('|', $option->getShortcut()) as $shortcut) {
237 $this->shortcuts[$shortcut] = $option->getName();
238 }
239 }
240
241 if ($option->isNegatable()) {
242 $negatedName = 'no-'.$option->getName();
243 if (isset($this->options[$negatedName])) {
244 throw new LogicException(sprintf('An option named "%s" already exists.', $negatedName));
245 }
246 $this->negations[$negatedName] = $option->getName();
247 }
248 }
249
250 /**
251 * Returns an InputOption by name.
252 *
253 * @throws InvalidArgumentException When option given doesn't exist
254 */
255 public function getOption(string $name): InputOption
256 {
257 if (!$this->hasOption($name)) {
258 throw new InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name));
259 }
260
261 return $this->options[$name];
262 }
263
264 /**
265 * Returns true if an InputOption object exists by name.
266 *
267 * This method can't be used to check if the user included the option when
268 * executing the command (use getOption() instead).
269 */
270 public function hasOption(string $name): bool
271 {
272 return isset($this->options[$name]);
273 }
274
275 /**
276 * Gets the array of InputOption objects.
277 *
278 * @return InputOption[]
279 */
280 public function getOptions(): array
281 {
282 return $this->options;
283 }
284
285 /**
286 * Returns true if an InputOption object exists by shortcut.
287 */
288 public function hasShortcut(string $name): bool
289 {
290 return isset($this->shortcuts[$name]);
291 }
292
293 /**
294 * Returns true if an InputOption object exists by negated name.
295 */
296 public function hasNegation(string $name): bool
297 {
298 return isset($this->negations[$name]);
299 }
300
301 /**
302 * Gets an InputOption by shortcut.
303 */
304 public function getOptionForShortcut(string $shortcut): InputOption
305 {
306 return $this->getOption($this->shortcutToName($shortcut));
307 }
308
309 /**
310 * @return array<string|bool|int|float|array|null>
311 */
312 public function getOptionDefaults(): array
313 {
314 $values = [];
315 foreach ($this->options as $option) {
316 $values[$option->getName()] = $option->getDefault();
317 }
318
319 return $values;
320 }
321
322 /**
323 * Returns the InputOption name given a shortcut.
324 *
325 * @throws InvalidArgumentException When option given does not exist
326 *
327 * @internal
328 */
329 public function shortcutToName(string $shortcut): string
330 {
331 if (!isset($this->shortcuts[$shortcut])) {
332 throw new InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut));
333 }
334
335 return $this->shortcuts[$shortcut];
336 }
337
338 /**
339 * Returns the InputOption name given a negation.
340 *
341 * @throws InvalidArgumentException When option given does not exist
342 *
343 * @internal
344 */
345 public function negationToName(string $negation): string
346 {
347 if (!isset($this->negations[$negation])) {
348 throw new InvalidArgumentException(sprintf('The "--%s" option does not exist.', $negation));
349 }
350
351 return $this->negations[$negation];
352 }
353
354 /**
355 * Gets the synopsis.
356 */
357 public function getSynopsis(bool $short = false): string
358 {
359 $elements = [];
360
361 if ($short && $this->getOptions()) {
362 $elements[] = '[options]';
363 } elseif (!$short) {
364 foreach ($this->getOptions() as $option) {
365 $value = '';
366 if ($option->acceptValue()) {
367 $value = sprintf(
368 ' %s%s%s',
369 $option->isValueOptional() ? '[' : '',
370 strtoupper($option->getName()),
371 $option->isValueOptional() ? ']' : ''
372 );
373 }
374
375 $shortcut = $option->getShortcut() ? sprintf('-%s|', $option->getShortcut()) : '';
376 $negation = $option->isNegatable() ? sprintf('|--no-%s', $option->getName()) : '';
377 $elements[] = sprintf('[%s--%s%s%s]', $shortcut, $option->getName(), $value, $negation);
378 }
379 }
380
381 if (\count($elements) && $this->getArguments()) {
382 $elements[] = '[--]';
383 }
384
385 $tail = '';
386 foreach ($this->getArguments() as $argument) {
387 $element = '<'.$argument->getName().'>';
388 if ($argument->isArray()) {
389 $element .= '...';
390 }
391
392 if (!$argument->isRequired()) {
393 $element = '['.$element;
394 $tail .= ']';
395 }
396
397 $elements[] = $element;
398 }
399
400 return implode(' ', $elements).$tail;
401 }
402}
diff --git a/vendor/symfony/console/Input/InputInterface.php b/vendor/symfony/console/Input/InputInterface.php
new file mode 100644
index 0000000..c177d96
--- /dev/null
+++ b/vendor/symfony/console/Input/InputInterface.php
@@ -0,0 +1,138 @@
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
12namespace Symfony\Component\Console\Input;
13
14use Symfony\Component\Console\Exception\InvalidArgumentException;
15use Symfony\Component\Console\Exception\RuntimeException;
16
17/**
18 * InputInterface is the interface implemented by all input classes.
19 *
20 * @author Fabien Potencier <fabien@symfony.com>
21 */
22interface InputInterface
23{
24 /**
25 * Returns the first argument from the raw parameters (not parsed).
26 */
27 public function getFirstArgument(): ?string;
28
29 /**
30 * Returns true if the raw parameters (not parsed) contain a value.
31 *
32 * This method is to be used to introspect the input parameters
33 * before they have been validated. It must be used carefully.
34 * Does not necessarily return the correct result for short options
35 * when multiple flags are combined in the same option.
36 *
37 * @param string|array $values The values to look for in the raw parameters (can be an array)
38 * @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal
39 */
40 public function hasParameterOption(string|array $values, bool $onlyParams = false): bool;
41
42 /**
43 * Returns the value of a raw option (not parsed).
44 *
45 * This method is to be used to introspect the input parameters
46 * before they have been validated. It must be used carefully.
47 * Does not necessarily return the correct result for short options
48 * when multiple flags are combined in the same option.
49 *
50 * @param string|array $values The value(s) to look for in the raw parameters (can be an array)
51 * @param string|bool|int|float|array|null $default The default value to return if no result is found
52 * @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal
53 */
54 public function getParameterOption(string|array $values, string|bool|int|float|array|null $default = false, bool $onlyParams = false): mixed;
55
56 /**
57 * Binds the current Input instance with the given arguments and options.
58 *
59 * @throws RuntimeException
60 */
61 public function bind(InputDefinition $definition): void;
62
63 /**
64 * Validates the input.
65 *
66 * @throws RuntimeException When not enough arguments are given
67 */
68 public function validate(): void;
69
70 /**
71 * Returns all the given arguments merged with the default values.
72 *
73 * @return array<string|bool|int|float|array|null>
74 */
75 public function getArguments(): array;
76
77 /**
78 * Returns the argument value for a given argument name.
79 *
80 * @throws InvalidArgumentException When argument given doesn't exist
81 */
82 public function getArgument(string $name): mixed;
83
84 /**
85 * Sets an argument value by name.
86 *
87 * @throws InvalidArgumentException When argument given doesn't exist
88 */
89 public function setArgument(string $name, mixed $value): void;
90
91 /**
92 * Returns true if an InputArgument object exists by name or position.
93 */
94 public function hasArgument(string $name): bool;
95
96 /**
97 * Returns all the given options merged with the default values.
98 *
99 * @return array<string|bool|int|float|array|null>
100 */
101 public function getOptions(): array;
102
103 /**
104 * Returns the option value for a given option name.
105 *
106 * @throws InvalidArgumentException When option given doesn't exist
107 */
108 public function getOption(string $name): mixed;
109
110 /**
111 * Sets an option value by name.
112 *
113 * @throws InvalidArgumentException When option given doesn't exist
114 */
115 public function setOption(string $name, mixed $value): void;
116
117 /**
118 * Returns true if an InputOption object exists by name.
119 */
120 public function hasOption(string $name): bool;
121
122 /**
123 * Is this input means interactive?
124 */
125 public function isInteractive(): bool;
126
127 /**
128 * Sets the input interactivity.
129 */
130 public function setInteractive(bool $interactive): void;
131
132 /**
133 * Returns a stringified representation of the args passed to the command.
134 *
135 * InputArguments MUST be escaped as well as the InputOption values passed to the command.
136 */
137 public function __toString(): string;
138}
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
12namespace Symfony\Component\Console\Input;
13
14use Symfony\Component\Console\Command\Command;
15use Symfony\Component\Console\Completion\CompletionInput;
16use Symfony\Component\Console\Completion\CompletionSuggestions;
17use Symfony\Component\Console\Completion\Suggestion;
18use Symfony\Component\Console\Exception\InvalidArgumentException;
19use Symfony\Component\Console\Exception\LogicException;
20
21/**
22 * Represents a command line option.
23 *
24 * @author Fabien Potencier <fabien@symfony.com>
25 */
26class 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}
diff --git a/vendor/symfony/console/Input/StreamableInputInterface.php b/vendor/symfony/console/Input/StreamableInputInterface.php
new file mode 100644
index 0000000..4a0dc01
--- /dev/null
+++ b/vendor/symfony/console/Input/StreamableInputInterface.php
@@ -0,0 +1,37 @@
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
12namespace Symfony\Component\Console\Input;
13
14/**
15 * StreamableInputInterface is the interface implemented by all input classes
16 * that have an input stream.
17 *
18 * @author Robin Chalas <robin.chalas@gmail.com>
19 */
20interface StreamableInputInterface extends InputInterface
21{
22 /**
23 * Sets the input stream to read from when interacting with the user.
24 *
25 * This is mainly useful for testing purpose.
26 *
27 * @param resource $stream The input stream
28 */
29 public function setStream($stream): void;
30
31 /**
32 * Returns the input stream.
33 *
34 * @return resource|null
35 */
36 public function getStream();
37}
diff --git a/vendor/symfony/console/Input/StringInput.php b/vendor/symfony/console/Input/StringInput.php
new file mode 100644
index 0000000..8357001
--- /dev/null
+++ b/vendor/symfony/console/Input/StringInput.php
@@ -0,0 +1,85 @@
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
12namespace Symfony\Component\Console\Input;
13
14use Symfony\Component\Console\Exception\InvalidArgumentException;
15
16/**
17 * StringInput represents an input provided as a string.
18 *
19 * Usage:
20 *
21 * $input = new StringInput('foo --bar="foobar"');
22 *
23 * @author Fabien Potencier <fabien@symfony.com>
24 */
25class StringInput extends ArgvInput
26{
27 public const REGEX_UNQUOTED_STRING = '([^\s\\\\]+?)';
28 public const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')';
29
30 /**
31 * @param string $input A string representing the parameters from the CLI
32 */
33 public function __construct(string $input)
34 {
35 parent::__construct([]);
36
37 $this->setTokens($this->tokenize($input));
38 }
39
40 /**
41 * Tokenizes a string.
42 *
43 * @return list<string>
44 *
45 * @throws InvalidArgumentException When unable to parse input (should never happen)
46 */
47 private function tokenize(string $input): array
48 {
49 $tokens = [];
50 $length = \strlen($input);
51 $cursor = 0;
52 $token = null;
53 while ($cursor < $length) {
54 if ('\\' === $input[$cursor]) {
55 $token .= $input[++$cursor] ?? '';
56 ++$cursor;
57 continue;
58 }
59
60 if (preg_match('/\s+/A', $input, $match, 0, $cursor)) {
61 if (null !== $token) {
62 $tokens[] = $token;
63 $token = null;
64 }
65 } elseif (preg_match('/([^="\'\s]+?)(=?)('.self::REGEX_QUOTED_STRING.'+)/A', $input, $match, 0, $cursor)) {
66 $token .= $match[1].$match[2].stripcslashes(str_replace(['"\'', '\'"', '\'\'', '""'], '', substr($match[3], 1, -1)));
67 } elseif (preg_match('/'.self::REGEX_QUOTED_STRING.'/A', $input, $match, 0, $cursor)) {
68 $token .= stripcslashes(substr($match[0], 1, -1));
69 } elseif (preg_match('/'.self::REGEX_UNQUOTED_STRING.'/A', $input, $match, 0, $cursor)) {
70 $token .= $match[1];
71 } else {
72 // should never happen
73 throw new InvalidArgumentException(sprintf('Unable to parse input near "... %s ...".', substr($input, $cursor, 10)));
74 }
75
76 $cursor += \strlen($match[0]);
77 }
78
79 if (null !== $token) {
80 $tokens[] = $token;
81 }
82
83 return $tokens;
84 }
85}