diff --git a/src/Symfony/Component/Console/Style/SymfonyStyle.php b/src/Symfony/Component/Console/Style/SymfonyStyle.php index 3e67213e90d3d..bcf30d80cbd3d 100644 --- a/src/Symfony/Component/Console/Style/SymfonyStyle.php +++ b/src/Symfony/Component/Console/Style/SymfonyStyle.php @@ -21,6 +21,7 @@ use Symfony\Component\Console\Helper\TableCell; use Symfony\Component\Console\Helper\TableSeparator; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\ConsoleOutputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\TrimmedBufferOutput; use Symfony\Component\Console\Question\ChoiceQuestion; @@ -38,6 +39,7 @@ class SymfonyStyle extends OutputStyle public const MAX_LINE_LENGTH = 120; private $input; + private $output; private $questionHelper; private $progressBar; private $lineLength; @@ -51,7 +53,7 @@ public function __construct(InputInterface $input, OutputInterface $output) $width = (new Terminal())->getWidth() ?: self::MAX_LINE_LENGTH; $this->lineLength = min($width - (int) (\DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH); - parent::__construct($output); + parent::__construct($this->output = $output); } /** @@ -186,15 +188,12 @@ public function caution($message) */ public function table(array $headers, array $rows) { - $style = clone Table::getStyleDefinition('symfony-style-guide'); - $style->setCellHeaderFormat('%s'); - - $table = new Table($this); - $table->setHeaders($headers); - $table->setRows($rows); - $table->setStyle($style); + $this->createTable() + ->setHeaders($headers) + ->setRows($rows) + ->render() + ; - $table->render(); $this->newLine(); } @@ -203,16 +202,13 @@ public function table(array $headers, array $rows) */ public function horizontalTable(array $headers, array $rows) { - $style = clone Table::getStyleDefinition('symfony-style-guide'); - $style->setCellHeaderFormat('%s'); - - $table = new Table($this); - $table->setHeaders($headers); - $table->setRows($rows); - $table->setStyle($style); - $table->setHorizontal(true); + $this->createTable() + ->setHorizontal(true) + ->setHeaders($headers) + ->setRows($rows) + ->render() + ; - $table->render(); $this->newLine(); } @@ -228,10 +224,6 @@ public function horizontalTable(array $headers, array $rows) */ public function definitionList(...$list) { - $style = clone Table::getStyleDefinition('symfony-style-guide'); - $style->setCellHeaderFormat('%s'); - - $table = new Table($this); $headers = []; $row = []; foreach ($list as $value) { @@ -252,13 +244,7 @@ public function definitionList(...$list) $row[] = current($value); } - $table->setHeaders($headers); - $table->setRows([$row]); - $table->setHorizontal(); - $table->setStyle($style); - - $table->render(); - $this->newLine(); + $this->horizontalTable($headers, [$row]); } /** @@ -349,6 +335,16 @@ public function createProgressBar(int $max = 0) return $progressBar; } + /** + * @see ProgressBar::iterate() + */ + public function progressIterate(iterable $iterable, int $max = null): iterable + { + yield from $this->createProgressBar()->iterate($iterable, $max); + + $this->newLine(2); + } + /** * @return mixed */ @@ -421,6 +417,15 @@ public function getErrorStyle() return new self($this->input, $this->getErrorOutput()); } + public function createTable(): Table + { + $output = $this->output instanceof ConsoleOutputInterface ? $this->output->section() : $this->output; + $style = clone Table::getStyleDefinition('symfony-style-guide'); + $style->setCellHeaderFormat('%s'); + + return (new Table($output))->setStyle($style); + } + private function getProgressBar(): ProgressBar { if (!$this->progressBar) { diff --git a/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/command/command_22.php b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/command/command_22.php new file mode 100644 index 0000000000000..6487bc3b1fbb2 --- /dev/null +++ b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/command/command_22.php @@ -0,0 +1,16 @@ +progressIterate(\range(1, 10)) as $step) { + // noop + } + + $style->writeln('end of progressbar'); +}; diff --git a/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/output/output_22.txt b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/output/output_22.txt new file mode 100644 index 0000000000000..e5d9f22e33ee1 --- /dev/null +++ b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/output/output_22.txt @@ -0,0 +1,4 @@ + 0/10 [░░░░░░░░░░░░░░░░░░░░░░░░░░░░] 0% + 10/10 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100% + +end of progressbar diff --git a/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php b/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php index 60ac39c15bced..982c267775f58 100644 --- a/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php +++ b/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php @@ -13,10 +13,12 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Formatter\OutputFormatter; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\ConsoleOutputInterface; +use Symfony\Component\Console\Output\ConsoleSectionOutput; use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; @@ -106,6 +108,39 @@ public function testGetErrorStyle() $io->getErrorStyle()->write(''); } + public function testCreateTableWithConsoleOutput() + { + $input = $this->createMock(InputInterface::class); + $output = $this->createMock(ConsoleOutputInterface::class); + $output + ->method('getFormatter') + ->willReturn(new OutputFormatter()); + $output + ->expects($this->once()) + ->method('section') + ->willReturn($this->createMock(ConsoleSectionOutput::class)); + + $style = new SymfonyStyle($input, $output); + + $style->createTable(); + } + + public function testCreateTableWithoutConsoleOutput() + { + $input = $this->createMock(InputInterface::class); + $output = $this->createMock(OutputInterface::class); + $output + ->method('getFormatter') + ->willReturn(new OutputFormatter()); + + $style = new SymfonyStyle($input, $output); + + $this->expectException(RuntimeException::class); + $this->expectDeprecationMessage('Output should be an instance of "Symfony\Component\Console\Output\ConsoleSectionOutput"'); + + $style->createTable()->appendRow(['row']); + } + public function testGetErrorStyleUsesTheCurrentOutputIfNoErrorOutputIsAvailable() { $output = $this->createMock(OutputInterface::class);