10000 [Console] Expose the original input arguments and options · symfony/symfony@11b9599 · GitHub
[go: up one dir, main page]

Skip to content

Commit 11b9599

Browse files
committed
[Console] Expose the original input arguments and options
PoC
1 parent 24f9ef8 commit 11b9599

File tree

6 files changed

+676
-40
lines changed

6 files changed

+676
-40
lines changed

src/Symfony/Component/Console/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ CHANGELOG
88
* Add `verbosity` argument to `mustRun` process helper method
99
* [BC BREAK] Add silent verbosity (`--silent`/`SHELL_VERBOSITY=-2`) to suppress all output, including errors
1010
* Add `OutputInterface::isSilent()`, `Output::isSilent()`, `OutputStyle::isSilent()` methods
11+
* Add `InputInterface::getRawArguments()`, `InputInterface::getRawOptions()` and `Input::unparse()` methods
1112

1213
7.1
1314
---

src/Symfony/Component/Console/Input/Input.php

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public function validate(): void
6363
$definition = $this->definition;
6464
$givenArguments = $this->arguments;
6565

66-
$missingArguments = array_filter(array_keys($definition->getArguments()), fn ($argument) => !\array_key_exists($argument, $givenArguments) && $definition->getArgument($argument)->isRequired());
66+
$missingArguments = array_filter(\array_keys($definition->getArguments()), fn ($argument) => !\array_key_exists($argument, $givenArguments) && $definition->getArgument($argument)->isRequired());
6767

6868
if (\count($missingArguments) > 0) {
6969
throw new RuntimeException(\sprintf('Not enough arguments (missing: "%s").', implode(', ', $missingArguments)));
@@ -85,6 +85,35 @@ public function getArguments(): array
8585
return array_merge($this->definition->getArgumentDefaults(), $this->arguments);
8686
}
8787

88+
/**
89+
* Returns all the given arguments NOT merged with the default values.
90+
*
91+
* @param bool $strip Whether to return the raw parameters (false) or the values after the command name (true)
92+
*
93+
* @return array<string|bool|int|float|null|array<string|bool|int|float|null>>
94+
*/
95+
public function getRawArguments(bool $strip = false): array
96+
{
97+
if (!$strip) {
98+
return $this->arguments;
99+
}
100+
101+
$arguments = [];
102+
$keep = false;
103+
foreach ($this->arguments as $argument) {
104+
if (!$keep && $argument === $this->getFirstArgument()) {
105+
$keep = true;
106+
107+
continue;
108+
}
109+
if ($keep) {
110+
$arguments[] = $argument;
111+
}
112+
}
113+
114+
return $arguments;
115+
}
116+
88117
public function getArgument(string $name): mixed
89118
{
90119
if (!$this->definition->hasArgument($name)) {
@@ -113,6 +142,16 @@ public function getOptions(): array
113142
return array_merge($this->definition->getOptionDefaults(), $this->options);
114143
}
115144

145+
/**
146+
* Returns all the given options NOT merged with the default values.
147+
*
148+
* @return array<string|bool|int|float|null|array<string|bool|int|float|null>>
149+
*/
150+
public function getRawOptions(): array
151+
{
152+
return $this->options;
153+
}
154+
116155
public function getOption(string $name): mixed
117156
{
118157
if ($this->definition->hasNegation($name)) {
@@ -171,4 +210,57 @@ public function getStream()
171210
{
172211
return $this->stream;
173212
}
213+
214+
/**
215+
* Returns a stringified representation of the options passed to the command.
216+
*
217+
* InputArguments MUST be escaped as well as the InputOption values passed to the command.
218+
*
219+
* @param string[] $optionNames Name of the options returned. If empty, all options are returned and non-passed or non-existent are ignored.
220+
*
221+
* @return list<string>
222+
*/
223+
public function unparse(array $optionNames = []): array
224+
{
225+
$rawOptions = $this->getRawOptions();
226+
227+
$filteredRawOptions = count($optionNames) === 0
228+
? $rawOptions
229+
: array_intersect_key($rawOptions, array_fill_keys($optionNames, ''),
230+
);
231+
232+
return array_map(
233+
fn (string $optionName) => $this->unparseOption(
234+
$this->definition->getOption($optionName),
235+
$optionName,
236+
$filteredRawOptions[$optionName],
237+
),
238+
array_keys($filteredRawOptions),
239+
);
240+
}
241+
242+
/**
243+
* @param string|bool|int|float|null|array<string|bool|int|float|null> $value
244+
*/
245+
private function unparseOption(
246+
InputOption $option,
247+
string $name,
248+
array|bool|float|int|string|null $value,
249+
): string
250+
{
251+
return match(true) {
252+
$option->isNegatable() => sprintf('--%s%s', $value ? '' : 'no-', $name),
253+
!$option->acceptValue() => sprintf('--%s', $name),
254+
$option->isArray() => implode('', array_map(fn($item) => $this->unparseOptionWithValue($name, $item), $value,)),
255+
default => $this->unparseOptionWithValue($name, $value),
256+
};
257+
}
258+
259+
private function unparseOptionWithValue(
260+
string $name,
261+
bool|float|int|string|null $value,
262+
): string
263+
{
264+
return sprintf('--%s=%s', $name, $this->escapeToken($value));
265+
}
174266
}

src/Symfony/Component/Console/Input/InputInterface.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
* InputInterface is the interface implemented by all input classes.
1919
*
2020
* @author Fabien Potencier <fabien@symfony.com>
21+
*
22+
* @method getRawArguments(bool $strip = false): array<string|bool|int|float|null|array<string|bool|int|float|null>> Returns all the given arguments NOT merged with the default values.
23+
* @method getRawOptions(): array<string|bool|int|float|null|array<string|bool|int|float|null>> Returns all the given options NOT merged with the default values.
2124
*/
2225
interface InputInterface
2326
{

0 commit comments

Comments
 (0)
0