From b90a3f12a1407f20ee625443350bb929da6de8ce Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Fri, 21 Sep 2018 19:07:33 +0200 Subject: [PATCH] [Console] Send the right exit code to console.terminate listeners --- src/Symfony/Component/Console/Application.php | 35 +++++++++---- .../Console/Tests/ApplicationTest.php | 50 +++++++++++++++++++ 2 files changed, 75 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index d1a21049ee..240a9ab7a8 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -129,15 +129,7 @@ class Application $this->renderException($e, $output); } - $exitCode = $e->getCode(); - if (is_numeric($exitCode)) { - $exitCode = (int) $exitCode; - if (0 === $exitCode) { - $exitCode = 1; - } - } else { - $exitCode = 1; - } + $exitCode = $this->getExitCodeForThrowable($e); } if ($this->autoExit) { @@ -873,7 +865,8 @@ class Application if ($x !== $event->getException()) { $e = $event->getException(); } - $exitCode = $e->getCode(); + + $exitCode = $this->getExitCodeForThrowable($e); } $event = new ConsoleTerminateEvent($command, $input, $output, $exitCode); @@ -1148,4 +1141,26 @@ class Application $this->add($command); } } + + /** + * Type hint omitted to be PHP5 compatible. + * + * @param \Exception|\Throwable $throwable + * + * @return int + */ + private function getExitCodeForThrowable($throwable) + { + $exitCode = $throwable->getCode(); + if (is_numeric($exitCode)) { + $exitCode = (int) $exitCode; + if (0 === $exitCode) { + $exitCode = 1; + } + } else { + $exitCode = 1; + } + + return $exitCode; + } } diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index 1664302dcf..8eb01d9f59 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -774,6 +774,31 @@ class ApplicationTest extends TestCase $this->assertSame(4, $exitCode, '->run() returns integer exit code extracted from raised exception'); } + public function testRunDispatchesIntegerExitCode() + { + $passedRightValue = false; + + // We can assume here that some other test asserts that the event is dispatched at all + $dispatcher = new EventDispatcher(); + $self = $this; + $dispatcher->addListener('console.terminate', function (ConsoleTerminateEvent $event) use ($self, &$passedRightValue) { + $passedRightValue = (4 === $event->getExitCode()); + }); + + $application = new Application(); + $application->setDispatcher($dispatcher); + $application->setAutoExit(false); + + $application->register('test')->setCode(function (InputInterface $input, OutputInterface $output) { + throw new \Exception('', 4); + }); + + $tester = new ApplicationTester($application); + $tester->run(array('command' => 'test')); + + $this->assertTrue($passedRightValue, '-> exit code 4 was passed in the console.terminate event'); + } + public function testRunReturnsExitCodeOneForExceptionCodeZero() { $exception = new \Exception('', 0); @@ -789,6 +814,31 @@ class ApplicationTest extends TestCase $this->assertSame(1, $exitCode, '->run() returns exit code 1 when exception code is 0'); } + public function testRunDispatchesExitCodeOneForExceptionCodeZero() + { + $passedRightValue = false; + + // We can assume here that some other test asserts that the event is dispatched at all + $dispatcher = new EventDispatcher(); + $self = $this; + $dispatcher->addListener('console.terminate', function (ConsoleTerminateEvent $event) use ($self, &$passedRightValue) { + $passedRightValue = (1 === $event->getExitCode()); + }); + + $application = new Application(); + $application->setDispatcher($dispatcher); + $application->setAutoExit(false); + + $application->register('test')->setCode(function (InputInterface $input, OutputInterface $output) { + throw new \Exception(); + }); + + $tester = new ApplicationTester($application); + $tester->run(array('command' => 'test')); + + $this->assertTrue($passedRightValue, '-> exit code 1 was passed in the console.terminate event'); + } + /** * @expectedException \LogicException * @expectedExceptionMessage An option with shortcut "e" already exists.