Merge branch '8.0' into 8.1

* 8.0:
  [Console] Fix `ApplicationTester` ignoring `interactive` and `verbosity` options when `SHELL_VERBOSITY` is set
This commit is contained in:
Nicolas Grekas
2026-03-06 15:01:29 +01:00
2 changed files with 64 additions and 1 deletions

View File

@@ -58,6 +58,28 @@ class ApplicationTester
$this->initOutput($options);
return $this->statusCode = $this->application->run($this->input, $this->output);
// Temporarily clear SHELL_VERBOSITY to prevent Application::configureIO
// from overriding the interactive and verbosity settings set above
$prevShellVerbosity = [getenv('SHELL_VERBOSITY'), $_ENV['SHELL_VERBOSITY'] ?? false, $_SERVER['SHELL_VERBOSITY'] ?? false];
if (\function_exists('putenv')) {
@putenv('SHELL_VERBOSITY');
}
unset($_ENV['SHELL_VERBOSITY'], $_SERVER['SHELL_VERBOSITY']);
try {
return $this->statusCode = $this->application->run($this->input, $this->output);
} finally {
if (false !== $prevShellVerbosity[0]) {
if (\function_exists('putenv')) {
@putenv('SHELL_VERBOSITY='.$prevShellVerbosity[0]);
}
}
if (false !== $prevShellVerbosity[1]) {
$_ENV['SHELL_VERBOSITY'] = $prevShellVerbosity[1];
}
if (false !== $prevShellVerbosity[2]) {
$_SERVER['SHELL_VERBOSITY'] = $prevShellVerbosity[2];
}
}
}
}

View File

@@ -11,6 +11,7 @@
namespace Symfony\Component\Console\Tests\Tester;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Helper\QuestionHelper;
@@ -91,6 +92,46 @@ class ApplicationTesterTest extends TestCase
$this->tester->assertCommandIsSuccessful('->getStatusCode() returns the status code');
}
#[DataProvider('provideShellVerbositySources')]
public function testShellVerbosityDoesNotOverrideInteractiveAndVerbosity(callable $setShellVerbosity, callable $cleanUp)
{
$setShellVerbosity();
try {
$application = new Application();
$application->setAutoExit(false);
$application->register('foo')
->setCode(static function ($input, $output) {
$output->writeln('foo');
})
;
$tester = new ApplicationTester($application);
$tester->run(['command' => 'foo'], ['interactive' => true]);
$this->assertTrue($tester->getInput()->isInteractive());
$this->assertSame('foo'.\PHP_EOL, $tester->getDisplay());
} finally {
$cleanUp();
}
}
public static function provideShellVerbositySources(): iterable
{
yield 'putenv' => [
static function () { putenv('SHELL_VERBOSITY=-1'); },
static function () { putenv('SHELL_VERBOSITY'); },
];
yield '$_ENV' => [
static function () { $_ENV['SHELL_VERBOSITY'] = '-1'; },
static function () { unset($_ENV['SHELL_VERBOSITY']); },
];
yield '$_SERVER' => [
static function () { $_SERVER['SHELL_VERBOSITY'] = '-1'; },
static function () { unset($_SERVER['SHELL_VERBOSITY']); },
];
}
public function testErrorOutput()
{
$application = new Application();