10000 feature #43595 [Console] `SymfonyStyle` enhancements (kbond) · symfony/symfony@1fdd7a8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1fdd7a8

Browse files
committed
feature #43595 [Console] SymfonyStyle enhancements (kbond)
This PR was squashed before being merged into the 5.4 branch. Discussion ---------- [Console] `SymfonyStyle` enhancements | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | n/a | License | MIT | Doc PR | todo Adds the following enhancements to `SymfonyStyle`: 1. Add `::progressIterate()` 2. Add `::createTable()` method to reduce duplication and add customization point 3. Use `ConsoleSectionOutput` when creating table (if available) - allows for creating "appendable" tables Commits ------- 6740ae5 [Console] `SymfonyStyle` enhancements
2 parents fe48ba6 + 6740ae5 commit 1fdd7a8

File tree

4 files changed

+89
-29
lines changed

4 files changed

+89
-29
lines changed

src/Symfony/Component/Console/Style/SymfonyStyle.php

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use Symfony\Component\Console\Helper\TableCell;
2222
use Symfony\Component\Console\Helper\TableSeparator;
2323
use Symfony\Component\Console\Input\InputInterface;
24+
use Symfony\Component\Console\Output\ConsoleOutputInterface;
2425
use Symfony\Component\Console\Output\OutputInterface;
2526
use Symfony\Component\Console\Output\TrimmedBufferOutput;
2627
use Symfony\Component\Console\Question\ChoiceQuestion;
@@ -38,6 +39,7 @@ class SymfonyStyle extends OutputStyle
3839
public const MAX_LINE_LENGTH = 120;
3940

4041
private $input;
42+
private $output;
4143
private $questionHelper;
4244
private $progressBar;
4345
private $lineLength;
@@ -51,7 +53,7 @@ public function __construct(InputInterface $input, OutputInterface $output)
5153
$width = (new Terminal())->getWidth() ?: self::MAX_LINE_LENGTH;
5254
$this->lineLength = min($width - (int) (\DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH);
5355

54-
parent::__construct($output);
56+
parent::__construct($this->output = $output);
5557
}
5658

5759
/**
@@ -186,15 +188,12 @@ public function caution($message)
186188
*/
187189
public function table(array $headers, array $rows)
188190
{
189-
$style = clone Table::getStyleDefinition('symfony-style-guide');
190-
$style->setCellHeaderFormat('<info>%s</info>');
191-
192-
$table = new Table($this);
193-
$table->setHeaders($headers);
194-
$table->setRows($rows);
195-
$table->setStyle($style);
191+
$this->createTable()
192+
->setHeaders($headers)
193+
->setRows($rows)
194+
->render()
195+
;
196196

197-
$table->render();
198197
$this->newLine();
199198
}
200199

@@ -203,16 +202,13 @@ public function table(array $headers, array $rows)
203202
*/
204203
public function horizontalTable(array $headers, array $rows)
205204
{
206-
$style = clone Table::getStyleDefinition('symfony-style-guide');
207-
$style->setCellHeaderFormat('<info>%s</info>');
208-
209-
$table = new Table($this);
210-
$table->setHeaders($headers);
211-
$table->setRows($rows);
212-
$table->setStyle($style);
213-
$table->setHorizontal(true);
205+
$this->createTable()
206+
->setHorizontal(true)
207+
->setHeaders($headers)
208+
->setRows($rows)
209+
->render()
210+
;
214211

215-
$table->render();
216212
$this->newLine();
217213
}
218214

@@ -228,10 +224,6 @@ public function horizontalTable(array $headers, array $rows)
228224
*/
229225
public function definitionList(...$list)
230226
{
231-
$style = clone Table::getStyleDefinition('symfony-style-guide');
232-
$style->setCellHeaderFormat('<info>%s</info>');
233-
234-
$table = new Table($this);
235227
$headers = [];
236228
$row = [];
237229
foreach ($list as $value) {
@@ -252,13 +244,7 @@ public function definitionList(...$list)
252244
$row[] = current($value);
253245
}
254246

255-
$table->setHeaders($headers);
256-
$table->setRows([$row]);
257-
$table->setHorizontal();
258-
$table->setStyle($style);
259-
260-
$table->render();
261-
$this->newLine();
247+
$this->horizontalTable($headers, [$row]);
262248
}
263249

264250
/**
@@ -349,6 +335,16 @@ public function createProgressBar(int $max = 0)
349335
return $progressBar;
350336
}
351337

338+
/**
339+
* @see ProgressBar::iterate()
340+
*/
341+
public function progressIterate(iterable $iterable, int $max = null): iterable
342+
{
343+
yield from $this->createProgressBar()->iterate($iterable, $max);
344+
345+
$this->newLine(2);
346+
}
347+
352348
/**
353349
* @return mixed
354350
*/
@@ -421,6 +417,15 @@ public function getErrorStyle()
421417
return new self($this->input, $this->getErrorOutput());
422418
}
423419

420+
public function createTable(): Table
421+
{
422+
$output = $this->output instanceof ConsoleOutputInterface ? $this->output->section() : $this->output;
423+
$style = clone Table::getStyleDefinition('symfony-style-guide');
424+
$style->setCellHeaderFormat('<info>%s</info>');
425+
426+
return (new Table($output))->setStyle($style);
427+
}
428+
424429
private function getProgressBar(): ProgressBar
425430
{
426431
if (!$this->progressBar) {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
use Symfony\Component\Console\Input\InputInterface;
4+
use Symfony\Component\Console\Output\OutputInterface;
5+
use Symfony\Component\Console\Style\SymfonyStyle;
6+
7+
// progressIterate
8+
return function (InputInterface $input, OutputInterface $output) {
9+
$style = new SymfonyStyle($input, $output);
10+
11+
foreach ($style->progressIterate(\range(1, 10)) as $step) {
12+
// noop
13+
}
14+
15+
$style->writeln('end of progressbar');
16+
};
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
0/10 [░░░░░░░░░░░░░░░░░░░░░░░░░░░░] 0%
2+
10/10 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
3+
4+
end of progressbar

src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Console\Command\Command;
16+
use Symfony\Component\Console\Exception\RuntimeException;
1617
use Symfony\Component\Console\Formatter\OutputFormatter;
1718
use Symfony\Component\Console\Input\ArrayInput;
1819
use Symfony\Component\Console\Input\InputInterface;
1920
use Symfony\Component\Console\Output\ConsoleOutputInterface;
21+
use Symfony\Component\Console\Output\ConsoleSectionOutput;
2022
use Symfony\Component\Console\Output\NullOutput;
2123
use Symfony\Component\Console\Output\OutputInterface;
2224
use Symfony\Component\Console\Style\SymfonyStyle;
@@ -106,6 +108,39 @@ public function testGetErrorStyle()
106108
$io->getErrorStyle()->write('');
107109
}
108110

111+
public function testCreateTableWithConsoleOutput()
112+
{
113+
$input = $this->createMock(InputInterface::class);
114+
$output = $this->createMock(ConsoleOutputInterface::class);
115+
$output
116+
->method('getFormatter')
117+
->willReturn(new OutputFormatter());
118+
$output
119+
->expects($this->once())
120+
->method('section')
121+
->willReturn($this->createMock(ConsoleSectionOutput::class));
122+
123+
$style = new SymfonyStyle($input, $output);
124+
125+
$style->createTable();
126+
}
127+
128+
public function testCreateTableWithoutConsoleOutput()
129+
{
130+
$input = $this->createMock(InputInterface::class);
131+
$output = $this->createMock(OutputInterface::class);
132+
$output
133+
->method('getFormatter')
134+
->willReturn(new OutputFormatter());
135+
136+
$style = new SymfonyStyle($input, $output);
137+
138+
$this->expectException(RuntimeException::class);
139+
$this->expectDeprecationMessage('Output should be an instance of "Symfony\Component\Console\Output\ConsoleSectionOutput"');
140+
141+
$style->createTable()->appendRow(['row']);
142+
}
143+
109144
public function testGetErrorStyleUsesTheCurrentOutputIfNoErrorOutputIsAvailable()
110145
{
111146
$output = $this->createMock(OutputInterface::class);

0 commit comments

Comments
 (0)
0