Skip to content

Commit 01bfc76

Browse files
committed
Merge branch '7.4' into 8.0
* 7.4: [Console] ensure `SHELL_VERBOSITY` is always restored properly [Console] Add support for `Cursor` helper in invokable commands [MonologBridge] Improve error when HttpClient contract is installed but not the component simplify LogoutListenerTest forbid HTTP method override of GET, HEAD, CONNECT and TRACE [HttpClient] Add option `auto_upgrade_http_version` to control how the request HTTP version is handled in `HttplugClient` and `Psr18Client` [Security] Allow multiple OIDC discovery endpoints [AssetMapper] Fix links to propshaft Document BC break in AbstractController::render
2 parents e35e66c + c77af87 commit 01bfc76

File tree

4 files changed

+52
-56
lines changed

4 files changed

+52
-56
lines changed

Application.php

Lines changed: 27 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,8 @@ public function run(?InputInterface $input = null, ?OutputInterface $output = nu
186186
}
187187
}
188188

189-
$prevShellVerbosity = getenv('SHELL_VERBOSITY');
189+
$empty = new \stdClass();
190+
$prevShellVerbosity = [$_ENV['SHELL_VERBOSITY'] ?? $empty, $_SERVER['SHELL_VERBOSITY'] ?? $empty, getenv('SHELL_VERBOSITY')];
190191

191192
try {
192193
$this->configureIO($input, $output);
@@ -228,18 +229,14 @@ public function run(?InputInterface $input = null, ?OutputInterface $output = nu
228229

229230
// SHELL_VERBOSITY is set by Application::configureIO so we need to unset/reset it
230231
// to its previous value to avoid one command verbosity to spread to other commands
231-
if (false === $prevShellVerbosity) {
232-
if (\function_exists('putenv')) {
233-
@putenv('SHELL_VERBOSITY');
234-
}
232+
if ($empty === $_ENV['SHELL_VERBOSITY'] = $prevShellVerbosity[0]) {
235233
unset($_ENV['SHELL_VERBOSITY']);
234+
}
235+
if ($empty === $_SERVER['SHELL_VERBOSITY'] = $prevShellVerbosity[1]) {
236236
unset($_SERVER['SHELL_VERBOSITY']);
237-
} else {
238-
if (\function_exists('putenv')) {
239-
@putenv('SHELL_VERBOSITY='.$prevShellVerbosity);
240-
}
241-
$_ENV['SHELL_VERBOSITY'] = $prevShellVerbosity;
242-
$_SERVER['SHELL_VERBOSITY'] = $prevShellVerbosity;
237+
}
238+
if (\function_exists('putenv')) {
239+
@putenv('SHELL_VERBOSITY'.(false === ($prevShellVerbosity[2] ?? false) ? '' : '='.$prevShellVerbosity[2]));
243240
}
244241
}
245242

@@ -949,57 +946,31 @@ protected function doRenderThrowable(\Throwable $e, OutputInterface $output): vo
949946
*/
950947
protected function configureIO(InputInterface $input, OutputInterface $output): void
951948
{
952-
if (true === $input->hasParameterOption(['--ansi'], true)) {
949+
if ($input->hasParameterOption(['--ansi'], true)) {
953950
$output->setDecorated(true);
954-
} elseif (true === $input->hasParameterOption(['--no-ansi'], true)) {
951+
} elseif ($input->hasParameterOption(['--no-ansi'], true)) {
955952
$output->setDecorated(false);
956953
}
957954

958-
if (true === $input->hasParameterOption(['--no-interaction', '-n'], true)) {
959-
$input->setInteractive(false);
960-
}
961-
962-
switch ($shellVerbosity = (int) getenv('SHELL_VERBOSITY')) {
963-
case -2:
964-
$output->setVerbosity(OutputInterface::VERBOSITY_SILENT);
965-
break;
966-
case -1:
967-
$output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
968-
break;
969-
case 1:
970-
$output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
971-
break;
972-
case 2:
973-
$output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE);
974-
break;
975-
case 3:
976-
$output->setVerbosity(OutputInterface::VERBOSITY_DEBUG);
977-
break;
978-
default:
979-
$shellVerbosity = 0;
980-
break;
981-
}
955+
$shellVerbosity = match (true) {
956+
$input->hasParameterOption(['--silent'], true) => -2,
957+
$input->hasParameterOption(['--quiet', '-q'], true) => -1,
958+
$input->hasParameterOption('-vvv', true) || $input->hasParameterOption('--verbose=3', true) || 3 === $input->getParameterOption('--verbose', false, true) => 3,
959+
$input->hasParameterOption('-vv', true) || $input->hasParameterOption('--verbose=2', true) || 2 === $input->getParameterOption('--verbose', false, true) => 2,
960+
$input->hasParameterOption('-v', true) || $input->hasParameterOption('--verbose=1', true) || $input->hasParameterOption('--verbose', true) || $input->getParameterOption('--verbose', false, true) => 1,
961+
default => (int) ($_ENV['SHELL_VERBOSITY'] ?? $_SERVER['SHELL_VERBOSITY'] ?? getenv('SHELL_VERBOSITY')),
962+
};
982963

983-
if (true === $input->hasParameterOption(['--silent'], true)) {
984-
$output->setVerbosity(OutputInterface::VERBOSITY_SILENT);
985-
$shellVerbosity = -2;
986-
} elseif (true === $input->hasParameterOption(['--quiet', '-q'], true)) {
987-
$output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
988-
$shellVerbosity = -1;
989-
} else {
990-
if ($input->hasParameterOption('-vvv', true) || $input->hasParameterOption('--verbose=3', true) || 3 === $input->getParameterOption('--verbose', false, true)) {
991-
$output->setVerbosity(OutputInterface::VERBOSITY_DEBUG);
992-
$shellVerbosity = 3;
993-
} elseif ($input->hasParameterOption('-vv', true) || $input->hasParameterOption('--verbose=2', true) || 2 === $input->getParameterOption('--verbose', false, true)) {
994-
$output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE);
995-
$shellVerbosity = 2;
996-
} elseif ($input->hasParameterOption('-v', true) || $input->hasParameterOption('--verbose=1', true) || $input->hasParameterOption('--verbose', true) || $input->getParameterOption('--verbose', false, true)) {
997-
$output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
998-
$shellVerbosity = 1;
999-
}
1000-
}
964+
$output->setVerbosity(match ($shellVerbosity) {
965+
-2 => OutputInterface::VERBOSITY_SILENT,
966+
-1 => OutputInterface::VERBOSITY_QUIET,
967+
1 => OutputInterface::VERBOSITY_VERBOSE,
968+
2 => OutputInterface::VERBOSITY_VERY_VERBOSE,
969+
3 => OutputInterface::VERBOSITY_DEBUG,
970+
default => ($shellVerbosity = 0) ?: $output->getVerbosity(),
971+
});
1001972

1002-
if (0 > $shellVerbosity) {
973+
if (0 > $shellVerbosity || $input->hasParameterOption(['--no-interaction', '-n'], true)) {
1003974
$input->setInteractive(false);
1004975
}
1005976

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ CHANGELOG
2424
* Add `#[MapInput]` attribute to support DTOs in commands
2525
* Add optional timeout for interaction in `QuestionHelper`
2626
* Add support for interactive invokable commands with `#[Interact]` and `#[Ask]` attributes
27+
* Add support for `Cursor` helper in invokable commands
2728

2829
7.3
2930
---

Command/InvokableCommand.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\Console\Attribute\Interact;
1717
use Symfony\Component\Console\Attribute\MapInput;
1818
use Symfony\Component\Console\Attribute\Option;
19+
use Symfony\Component\Console\Cursor;
1920
use Symfony\Component\Console\Exception\LogicException;
2021
use Symfony\Component\Console\Exception\RuntimeException;
2122
use Symfony\Component\Console\Input\InputArgument;
@@ -159,6 +160,7 @@ private function getParameters(\ReflectionFunction $function, InputInterface $in
159160
$parameters[] = match ($type->getName()) {
160161
InputInterface::class => $input,
161162
OutputInterface::class => $output,
163+
Cursor::class => new Cursor($output),
162164
SymfonyStyle::class => new SymfonyStyle($input, $output),
163165
Application::class => $this->command->getApplication(),
164166
default => throw new RuntimeException(\sprintf('Unsupported type "%s" for parameter "$%s".', $type->getName(), $parameter->getName())),

Tests/Command/InvokableCommandTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,22 @@
1414
use PHPUnit\Framework\Assert;
1515
use PHPUnit\Framework\Attributes\DataProvider;
1616
use PHPUnit\Framework\TestCase;
17+
use Symfony\Component\Console\Application;
1718
use Symfony\Component\Console\Attribute\Argument;
1819
use Symfony\Component\Console\Attribute\Option;
1920
use Symfony\Component\Console\Command\Command;
2021
use Symfony\Component\Console\Completion\CompletionInput;
2122
use Symfony\Component\Console\Completion\CompletionSuggestions;
2223
use Symfony\Component\Console\Completion\Suggestion;
24+
use Symfony\Component\Console\Cursor;
2325
use Symfony\Component\Console\Exception\InvalidArgumentException;
2426
use Symfony\Component\Console\Exception\InvalidOptionException;
2527
use Symfony\Component\Console\Exception\LogicException;
2628
use Symfony\Component\Console\Input\ArrayInput;
2729
use Symfony\Component\Console\Input\InputInterface;
2830
use Symfony\Component\Console\Output\NullOutput;
2931
use Symfony\Component\Console\Output\OutputInterface;
32+
use Symfony\Component\Console\Style\SymfonyStyle;
3033
use Symfony\Component\Console\Tests\Fixtures\InvokableTestCommand;
3134

3235
class InvokableCommandTest extends TestCase
@@ -462,6 +465,25 @@ public function testInvalidRequiredValueOptionEvenWithDefault()
462465
$command->run(new ArrayInput(['--a' => null]), new NullOutput());
463466
}
464467

468+
public function testHelpersInjection()
469+
{
470+
$command = new Command('foo');
471+
$command->setApplication(new Application());
472+
$command->setCode(function (
473+
InputInterface $input,
474+
OutputInterface $output,
475+
Cursor $cursor,
476+
SymfonyStyle $io,
477+
Application $application,
478+
): int {
479+
$this->addToAssertionCount(1);
480+
481+
return 0;
482+
});
483+
484+
$command->run(new ArrayInput([]), new NullOutput());
485+
}
486+
465487
public function getSuggestedRoles(CompletionInput $input): array
466488
{
467489
return ['ROLE_ADMIN', 'ROLE_USER'];

0 commit comments

Comments
 (0)