Skip to content

Commit

Permalink
[Console] allow configuring exit code behavior in RunCommandMessage
Browse files Browse the repository at this point in the history
  • Loading branch information
kbond committed Jul 28, 2023
1 parent e2922e6 commit 0cd0b54
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@
*/
final class RunCommandFailedException extends RuntimeException
{
public function __construct(\Throwable $exception, public readonly RunCommandContext $context)
public function __construct(\Throwable|string $exception, public readonly RunCommandContext $context)
{
parent::__construct($exception->getMessage(), $exception->getCode(), $exception);
parent::__construct(
$exception instanceof \Throwable ? $exception->getMessage() : $exception,
$exception instanceof \Throwable ? $exception->getCode() : 0,
$exception instanceof \Throwable ? $exception : null,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ final class RunCommandContext extends RunCommandMessage
{
public function __construct(RunCommandMessage $message, public readonly int $exitCode, public readonly string $output)
{
parent::__construct($message->input, $message->catchExceptions);
parent::__construct($message->input, $message->throwOnNonSuccess, $message->catchExceptions);
}
}
7 changes: 7 additions & 0 deletions src/Symfony/Component/Console/Messenger/RunCommandMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,20 @@

namespace Symfony\Component\Console\Messenger;

use Symfony\Component\Console\Exception\RunCommandFailedException;

/**
* @author Kevin Bond <kevinbond@gmail.com>
*/
class RunCommandMessage implements \Stringable
{
/**
* @param bool $throwOnNonSuccess If the command has a non-zero exit code, throw {@see RunCommandFailedException}
* @param bool $catchExceptions @see Application::setCatchExceptions()
*/
public function __construct(
public readonly string $input,
public readonly bool $throwOnNonSuccess = true,
public readonly bool $catchExceptions = false,
) {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ public function __invoke(RunCommandMessage $message): RunCommandContext
throw new RunCommandFailedException($e, new RunCommandContext($message, Command::FAILURE, $output->fetch()));
}

if ($message->throwOnNonSuccess && Command::SUCCESS !== $exitCode) {
throw new RunCommandFailedException(sprintf('Command "%s" exited with code "%s".', $message->input, $exitCode), new RunCommandContext($message, $exitCode, $output->fetch()));
}

return new RunCommandContext($message, $exitCode, $output->fetch());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\RunCommandFailedException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Messenger\RunCommandMessage;
use Symfony\Component\Console\Messenger\RunCommandMessageHandler;
use Symfony\Component\Console\Output\OutputInterface;
Expand Down Expand Up @@ -55,13 +56,31 @@ public function testExecutesCommandThatThrowsException()
public function testExecutesCommandThatCatchesThrownException()
{
$handler = new RunCommandMessageHandler($this->createApplicationWithCommand());
$context = $handler(new RunCommandMessage('test:command --throw -v', catchExceptions: true));
$context = $handler(new RunCommandMessage('test:command --throw -v', throwOnNonSuccess: false, catchExceptions: true));

$this->assertSame(1, $context->exitCode);
$this->assertStringContainsString('[RuntimeException]', $context->output);
$this->assertStringContainsString('exception message', $context->output);
}

public function testThrowOnNonSuccess()
{
$handler = new RunCommandMessageHandler($this->createApplicationWithCommand());

try {
$handler(new RunCommandMessage('test:command --exit=1'));
} catch (RunCommandFailedException $e) {
$this->assertSame(1, $e->context->exitCode);
$this->assertStringContainsString('some message', $e->context->output);
$this->assertSame('Command "test:command --exit=1" exited with code "1".', $e->getMessage());
$this->assertNull($e->getPrevious());

return;
}

$this->fail('Exception not thrown.');
}

private function createApplicationWithCommand(): Application
{
$application = new Application();
Expand All @@ -73,6 +92,7 @@ public function configure(): void
$this
->setName('test:command')
->addOption('throw')
->addOption('exit', null, InputOption::VALUE_REQUIRED, 0)
;
}

Expand All @@ -84,7 +104,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
throw new \RuntimeException('exception message');
}

return Command::SUCCESS;
return (int) $input->getOption('exit');
}
},
]);
Expand Down

0 comments on commit 0cd0b54

Please sign in to comment.