Skip to content

Commit b030c24

Browse files
TomasVotrubafabpot
authored andcommitted
[Console] ProgressBar - adjust to the window width (static)
1 parent 7ccfdb4 commit b030c24

File tree

5 files changed

+307
-143
lines changed

5 files changed

+307
-143
lines changed

src/Symfony/Component/Console/Application.php

Lines changed: 15 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
3737
use Symfony\Component\Console\Exception\CommandNotFoundException;
3838
use Symfony\Component\Console\Exception\LogicException;
39+
use Symfony\Component\Console\Terminal\TerminalDimensionsProvider;
3940
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
4041

4142
/**
@@ -65,20 +66,24 @@ class Application
6566
private $definition;
6667
private $helperSet;
6768
private $dispatcher;
68-
private $terminalDimensions;
6969
private $defaultCommand;
7070
private $singleCommand;
7171

7272
/**
73-
* Constructor.
74-
*
75-
* @param string $name The name of the application
76-
* @param string $version The version of the application
73+
* @var TerminalDimensionsProvider
7774
*/
78-
public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN')
75+
private $terminalDimensionsProvider;
76+
77+
/**
78+
* @param string $name The name of the application
79+
* @param string $version The version of the application
80+
* @param TerminalDimensionsProvider $terminalDimensionsProvider
81+
*/
82+
public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN', TerminalDimensionsProvider $terminalDimensionsProvider = null)
7983
{
8084
$this->name = $name;
8185
$this->version = $version;
86+
$this->terminalDimensionsProvider = $terminalDimensionsProvider ?: new TerminalDimensionsProvider();
8287
$this->defaultCommand = 'list';
8388
$this->helperSet = $this->getDefaultHelperSet();
8489
$this->definition = $this->getDefaultInputDefinition();
@@ -692,9 +697,7 @@ public function renderException(\Exception $e, OutputInterface $output)
692697
*/
693698
protected function getTerminalWidth()
694699
{
695-
$dimensions = $this->getTerminalDimensions();
696-
697-
return $dimensions[0];
700+
return $this->terminalDimensionsProvider->getTerminalWidth();
698701
}
699702

700703
/**
@@ -704,9 +707,7 @@ protected function getTerminalWidth()
704707
*/
705708
protected function getTerminalHeight()
706709
{
707-
$dimensions = $this->getTerminalDimensions();
708-
709-
return $dimensions[1];
710+
return $this->terminalDimensionsProvider->getTerminalWidth();
710711
}
711712

712713
/**
@@ -716,33 +717,7 @@ protected function getTerminalHeight()
716717
*/
717718
public function getTerminalDimensions()
718719
{
719-
if ($this->terminalDimensions) {
720-
return $this->terminalDimensions;
721-
}
722-
723-
if ('\\' === DIRECTORY_SEPARATOR) {
724-
// extract [w, H] from "wxh (WxH)"
725-
if (preg_match('/^(\d+)x\d+ \(\d+x(\d+)\)$/', trim(getenv('ANSICON')), $matches)) {
726-
return array((int) $matches[1], (int) $matches[2]);
727-
}
728-
// extract [w, h] from "wxh"
729-
if (preg_match('/^(\d+)x(\d+)$/', $this->getConsoleMode(), $matches)) {
730-
return array((int) $matches[1], (int) $matches[2]);
731-
}
732-
}
733-
734-
if ($sttyString = $this->getSttyColumns()) {
735-
// extract [w, h] from "rows h; columns w;"
736-
if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) {
737-
return array((int) $matches[2], (int) $matches[1]);
738-
}
739-
// extract [w, h] from "; h rows; w columns"
740-
if (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) {
741-
return array((int) $matches[2], (int) $matches[1]);
742-
}
743-
}
744-
745-
return array(null, null);
720+
return $this->terminalDimensionsProvider->getTerminalDimensions();
746721
}
747722

748723
/**
@@ -757,7 +732,7 @@ public function getTerminalDimensions()
757732
*/
758733
public function setTerminalDimensions($width, $height)
759734
{
760-
$this->terminalDimensions = array($width, $height);
735+
$this->terminalDimensionsProvider->setTerminalDimensions($width, $height);
761736

762737
return $this;
763738
}
@@ -927,54 +902,6 @@ protected function getDefaultHelperSet()
927902
));
928903
}
929904

930-
/**
931-
* Runs and parses stty -a if it's available, suppressing any error output.
932-
*
933-
* @return string
934-
*/
935-
private function getSttyColumns()
936-
{
937-
if (!function_exists('proc_open')) {
938-
return;
939-
}
940-
941-
$descriptorspec = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
942-
$process = proc_open('stty -a | grep columns', $descriptorspec, $pipes, null, null, array('suppress_errors' => true));
943-
if (is_resource($process)) {
944-
$info = stream_get_contents($pipes[1]);
945-
fclose($pipes[1]);
946-
fclose($pipes[2]);
947-
proc_close($process);
948-
949-
return $info;
950-
}
951-
}
952-
953-
/**
954-
* Runs and parses mode CON if it's available, suppressing any error output.
955-
*
956-
* @return string <width>x<height> or null if it could not be parsed
957-
*/
958-
private function getConsoleMode()
959-
{
960-
if (!function_exists('proc_open')) {
961-
return;
962-
}
963-
964-
$descriptorspec = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
965-
$process = proc_open('mode CON', $descriptorspec, $pipes, null, null, array('suppress_errors' => true));
966-
if (is_resource($process)) {
967-
$info = stream_get_contents($pipes[1]);
968-
fclose($pipes[1]);
969-
fclose($pipes[2]);
970-
proc_close($process);
971-
972-
if (preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) {
973-
return $matches[2].'x'.$matches[1];
974-
}
975-
}
976-
}
977-
978905
/**
979906
* Returns abbreviated suggestions in string format.
980907
*

src/Symfony/Component/Console/Helper/ProgressBar.php

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Component\Console\Output\ConsoleOutputInterface;
1515
use Symfony\Component\Console\Output\OutputInterface;
1616
use Symfony\Component\Console\Exception\LogicException;
17+
use Symfony\Component\Console\Terminal\TerminalDimensionsProvider;
1718

1819
/**
1920
* The ProgressBar provides helpers to display progress output.
@@ -49,19 +50,24 @@ class ProgressBar
4950
private static $formats;
5051

5152
/**
52-
* Constructor.
53-
*
54-
* @param OutputInterface $output An OutputInterface instance
55-
* @param int $max Maximum steps (0 if unknown)
53+
* @var TerminalDimensionsProvider
54+
*/
55+
private $terminalDimensionsProvider;
56+
57+
/**
58+
* @param OutputInterface $output An OutputInterface instance
59+
* @param int $max Maximum steps (0 if unknown)
60+
* @param TerminalDimensionsProvider $terminalDimensionsProvider
5661
*/
57-
public function __construct(OutputInterface $output, $max = 0)
62+
public function __construct(OutputInterface $output, $max = 0, TerminalDimensionsProvider $terminalDimensionsProvider = null)
5863
{
5964
if ($output instanceof ConsoleOutputInterface) {
6065
$output = $output->getErrorOutput();
6166
}
6267

6368
$this->output = $output;
6469
$this->setMaxSteps($max);
70+
$this->terminalDimensionsProvider = $terminalDimensionsProvider ?: new TerminalDimensionsProvider();
6571

6672
if (!$this->output->isDecorated()) {
6773
// disable overwrite when output does not support ANSI codes.
@@ -217,7 +223,7 @@ public function getProgressPercent()
217223
*/
218224
public function setBarWidth($size)
219225
{
220-
$this->barWidth = (int) $size;
226+
$this->barWidth = max(1, (int) $size);
221227
}
222228

223229
/**
@@ -412,21 +418,9 @@ public function display()
412418
$this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
413419
}
414420

415-
$this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) {
416-
if ($formatter = $this::getPlaceholderFormatterDefinition($matches[1])) {
417-
$text = call_user_func($formatter, $this, $this->output);
418-
} elseif (isset($this->messages[$matches[1]])) {
419-
$text = $this->messages[$matches[1]];
420-
} else {
421-
return $matches[0];
422-
}
423-
424-
if (isset($matches[2])) {
425-
$text = sprintf('%'.$matches[2], $text);
426-
}
427-
428-
return $text;
429-
}, $this->format));
421+
$line = $this->buildLine();
422+
$line = $this->adjustLineWidthToTerminalWidth($line);
423+
$this->overwrite($line);
430424
}
431425

432426
/**
@@ -592,4 +586,45 @@ private static function initFormats()
592586
'debug_nomax' => ' %current% [%bar%] %elapsed:6s% %memory:6s%',
593587
);
594588
}
589+
590+
/**
591+
* @return string
592+
*/
593+
private function buildLine()
594+
{
595+
return preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) {
596+
if ($formatter = $this::getPlaceholderFormatterDefinition($matches[1])) {
597+
$text = call_user_func($formatter, $this, $this->output);
598+
} elseif (isset($this->messages[$matches[1]])) {
599+
$text = $this->messages[$matches[1]];
600+
} else {
601+
return $matches[0];
602+
}
603+
604+
if (isset($matches[2])) {
605+
$text = sprintf('%'.$matches[2], $text);
606+
}
607+
608+
return $text;
609+
}, $this->format);
610+
}
611+
612+
/**
613+
* @param string $line
614+
*
615+
* @return bool
616+
*/
617+
private function adjustLineWidthToTerminalWidth($line)
618+
{
619+
$lineLength = Helper::strlenWithoutDecoration($this->output->getFormatter(), $line);
620+
$terminalWidth = $this->terminalDimensionsProvider->getTerminalWidth();
621+
if ($lineLength > $terminalWidth) {
622+
$newBarWidth = $this->barWidth - $lineLength + $terminalWidth;
623+
$this->setBarWidth($newBarWidth);
624+
625+
return $this->buildLine();
626+
}
627+
628+
return $line;
629+
}
595630
}

0 commit comments

Comments
 (0)