switched to use COLUMNS and LINES env vars to change terminal dimensions

This commit is contained in:
Fabien Potencier 2016-06-10 08:21:21 +02:00
parent bf7a5c58a9
commit 2f81247005
6 changed files with 84 additions and 112 deletions

View File

@ -684,26 +684,16 @@ class Application
}
}
/**
* Returns the current terminal.
*
* @return Terminal
*/
public function getTerminal()
{
return $this->terminal;
}
/**
* Tries to figure out the terminal width in which this application runs.
*
* @return int|null
*
* @deprecated since version 3.2, to be removed in 4.0. Use the getTerminal() method instead.
* @deprecated since version 3.2, to be removed in 4.0. Create a Terminal instance instead.
*/
protected function getTerminalWidth()
{
@trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Use getTerminal() instead.', __METHOD__, ArgumentResolverInterface::class), E_USER_DEPRECATED);
@trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Create a Terminal instance instead.', __METHOD__, ArgumentResolverInterface::class), E_USER_DEPRECATED);
return $this->terminal->getWidth();
}
@ -713,11 +703,11 @@ class Application
*
* @return int|null
*
* @deprecated since version 3.2, to be removed in 4.0. Use the getTerminal() method instead.
* @deprecated since version 3.2, to be removed in 4.0. Create a Terminal instance instead.
*/
protected function getTerminalHeight()
{
@trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Use getTerminal() instead.', __METHOD__, ArgumentResolverInterface::class), E_USER_DEPRECATED);
@trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Create a Terminal instance instead.', __METHOD__, ArgumentResolverInterface::class), E_USER_DEPRECATED);
return $this->terminal->getHeight();
}
@ -727,11 +717,11 @@ class Application
*
* @return array Array containing width and height
*
* @deprecated since version 3.2, to be removed in 4.0. Use the getTerminal() method instead.
* @deprecated since version 3.2, to be removed in 4.0. Create a Terminal instance instead.
*/
public function getTerminalDimensions()
{
@trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Use getTerminal() instead.', __METHOD__, ArgumentResolverInterface::class), E_USER_DEPRECATED);
@trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Create a Terminal instance instead.', __METHOD__, ArgumentResolverInterface::class), E_USER_DEPRECATED);
return array($this->terminal->getWidth(), $this->terminal->getHeight());
}
@ -746,14 +736,14 @@ class Application
*
* @return Application The current application
*
* @deprecated since version 3.2, to be removed in 4.0. Use the getTerminal() method instead.
* @deprecated since version 3.2, to be removed in 4.0. Set the COLUMNS and LINES env vars instead.
*/
public function setTerminalDimensions($width, $height)
{
@trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Use getTerminal() instead.', __METHOD__, ArgumentResolverInterface::class), E_USER_DEPRECATED);
@trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Set the COLUMNS and LINES env vars instead.', __METHOD__, ArgumentResolverInterface::class), E_USER_DEPRECATED);
$this->terminal->setWidth($width);
$this->terminal->setHeight($height);
putenv('COLUMNS='.$width);
putenv('LINES='.$height);
return $this;
}

View File

@ -436,20 +436,6 @@ class ProgressBar
$this->overwrite('');
}
/**
* Gets the terminal.
*
* Can be useful to force terminal dimensions for functional tests.
*
* @return Terminal
*
* @internal
*/
public function getTerminal()
{
return $this->terminal;
}
/**
* Sets the progress bar format.
*

View File

@ -13,8 +13,8 @@ namespace Symfony\Component\Console;
class Terminal
{
private $width;
private $height;
private static $width;
private static $height;
/**
* Gets the terminal width.
@ -23,21 +23,15 @@ class Terminal
*/
public function getWidth()
{
if (null === $this->width) {
$this->initDimensions();
if ($width = trim(getenv('COLUMNS'))) {
return (int) $width;
}
return $this->width;
}
if (null === self::$width) {
self::initDimensions();
}
/**
* Sets the terminal width.
*
* @param int $width
*/
public function setWidth($width)
{
$this->width = $width;
return self::$width;
}
/**
@ -47,59 +41,41 @@ class Terminal
*/
public function getHeight()
{
if (null === $this->height) {
$this->initDimensions();
if ($height = trim(getenv('LINES'))) {
return (int) $height;
}
return $this->height;
}
/**
* Sets the terminal height.
*
* @param int $height
*/
public function setHeight($height)
{
$this->height = $height;
}
private function initDimensions()
{
if (null !== $this->width && null !== $this->height) {
return;
if (null === self::$height) {
self::initDimensions();
}
$width = $height = null;
if ($this->isWindowsEnvironment()) {
if (preg_match('/^(\d+)x\d+ \(\d+x(\d+)\)$/', trim(getenv('ANSICON')), $matches)) {
return self::$height;
}
private static function initDimensions()
{
if ('\\' === DIRECTORY_SEPARATOR) {
if (preg_match('/^(\d+)x(\d+)(?: \((\d+)x(\d+)\))?$/', trim(getenv('ANSICON')), $matches)) {
// extract [w, H] from "wxh (WxH)"
$width = (int) $matches[1];
$height = (int) $matches[2];
} elseif (null != $dimensions = $this->getConsoleMode()) {
// or [w, h] from "wxh"
self::$width = (int) $matches[1];
self::$height = isset($matches[4]) ? (int) $matches[4] : (int) $matches[2];
} elseif (null != $dimensions = self::getConsoleMode()) {
// extract [w, h] from "wxh"
$width = $dimensions[0];
$height = $dimensions[1];
self::$width = (int) $dimensions[0];
self::$height = (int) $dimensions[1];
}
} elseif ($sttyString = $this->getSttyColumns()) {
} elseif ($sttyString = self::getSttyColumns()) {
if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) {
// extract [w, h] from "rows h; columns w;"
$width = (int) $matches[1];
$height = (int) $matches[2];
self::$width = (int) $matches[2];
self::$height = (int) $matches[1];
} elseif (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) {
// extract [w, h] from "; h rows; w columns"
$width = (int) $matches[2];
$heighth = (int) $matches[1];
self::$width = (int) $matches[2];
self::$height = (int) $matches[1];
}
}
if (null === $this->width) {
$this->width = $width;
}
if (null === $this->height) {
$this->height = $height;
}
}
/**
@ -107,7 +83,7 @@ class Terminal
*
* @return array|null An array composed of the width and the height or null if it could not be parsed
*/
private function getConsoleMode()
private static function getConsoleMode()
{
if (!function_exists('proc_open')) {
return;
@ -135,7 +111,7 @@ class Terminal
*
* @return string
*/
private function getSttyColumns()
private static function getSttyColumns()
{
if (!function_exists('proc_open')) {
return;
@ -156,12 +132,4 @@ class Terminal
return $info;
}
}
/**
* @return bool
*/
private function isWindowsEnvironment()
{
return '\\' === DIRECTORY_SEPARATOR;
}
}

View File

@ -478,7 +478,7 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
{
$application = new Application();
$application->setAutoExit(false);
$application->getTerminal()->setWidth(120);
putenv('COLUMNS=120');
$tester = new ApplicationTester($application);
$application->setCatchExceptions(true);
@ -514,7 +514,7 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
{
$application = new Application();
$application->setAutoExit(false);
$application->getTerminal()->setWidth(120);
putenv('COLUMNS=120');
$tester = new ApplicationTester($application);
$tester->run(array('command' => 'foo'), array('decorated' => false, 'capture_stderr_separately' => true));
@ -544,18 +544,19 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
$application = new Application();
$application->setAutoExit(false);
$application->getTerminal()->setWidth(32);
putenv('COLUMNS=32');
$tester = new ApplicationTester($application);
$tester->run(array('command' => 'foo'), array('decorated' => false, 'capture_stderr_separately' => true));
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception4.txt', $tester->getErrorOutput(true), '->renderException() wraps messages when they are bigger than the terminal');
putenv('COLUMNS=120');
}
public function testRenderExceptionWithDoubleWidthCharacters()
{
$application = new Application();
$application->setAutoExit(false);
$application->getTerminal()->setWidth(120);
putenv('COLUMNS=120');
$application->register('foo')->setCode(function () {
throw new \Exception('エラーメッセージ');
});
@ -569,13 +570,14 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
$application = new Application();
$application->setAutoExit(false);
$application->getTerminal()->setWidth(32);
putenv('COLUMNS=32');
$application->register('foo')->setCode(function () {
throw new \Exception('コマンドの実行中にエラーが発生しました。');
});
$tester = new ApplicationTester($application);
$tester->run(array('command' => 'foo'), array('decorated' => false, 'capture_stderr_separately' => true));
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth2.txt', $tester->getErrorOutput(true), '->renderException() wraps messages when they are bigger than the terminal');
putenv('COLUMNS=120');
}
public function testRun()

View File

@ -522,9 +522,10 @@ class ProgressBarTest extends \PHPUnit_Framework_TestCase
$output = $this->getOutputStream();
$bar = new ProgressBar($output);
$bar->getTerminal()->setWidth(12);
putenv('COLUMNS=12');
$bar->start();
$bar->advance();
putenv('COLUMNS=120');
rewind($output->getStream());
$this->assertEquals(
@ -577,6 +578,8 @@ class ProgressBarTest extends \PHPUnit_Framework_TestCase
public function testAnsiColorsAndEmojis()
{
putenv('COLUMNS=156');
$bar = new ProgressBar($output = $this->getOutputStream(), 15);
ProgressBar::setPlaceholderFormatterDefinition('memory', function (ProgressBar $bar) {
static $i = 0;
@ -592,10 +595,6 @@ class ProgressBarTest extends \PHPUnit_Framework_TestCase
$bar->setMessage('Starting the demo... fingers crossed', 'title');
$bar->start();
$bar->setMessage('Looks good to me...', 'title');
$bar->advance(4);
$bar->setMessage('Thanks, bye', 'title');
$bar->finish();
rewind($output->getStream());
$this->assertEquals(
@ -603,12 +602,32 @@ class ProgressBarTest extends \PHPUnit_Framework_TestCase
" \033[44;37m Starting the demo... fingers crossed \033[0m\n".
' 0/15 '.$progress.str_repeat($empty, 26)." 0%\n".
" \xf0\x9f\x8f\x81 < 1 sec \033[44;37m 0 B \033[0m"
).
),
stream_get_contents($output->getStream())
);
ftruncate($output->getStream(), 0);
rewind($output->getStream());
$bar->setMessage('Looks good to me...', 'title');
$bar->advance(4);
rewind($output->getStream());
$this->assertEquals(
$this->generateOutput(
" \033[44;37m Looks good to me... \033[0m\n".
' 4/15 '.str_repeat($done, 7).$progress.str_repeat($empty, 19)." 26%\n".
" \xf0\x9f\x8f\x81 < 1 sec \033[41;37m 97 KiB \033[0m"
).
),
stream_get_contents($output->getStream())
);
ftruncate($output->getStream(), 0);
rewind($output->getStream());
$bar->setMessage('Thanks, bye', 'title');
$bar->finish();
rewind($output->getStream());
$this->assertEquals(
$this->generateOutput(
" \033[44;37m Thanks, bye \033[0m\n".
' 15/15 '.str_repeat($done, 28)." 100%\n".
@ -616,6 +635,7 @@ class ProgressBarTest extends \PHPUnit_Framework_TestCase
),
stream_get_contents($output->getStream())
);
putenv('COLUMNS=120');
}
public function testSetFormat()

View File

@ -17,10 +17,16 @@ class TerminalTest extends \PHPUnit_Framework_TestCase
{
public function test()
{
putenv('COLUMNS=100');
putenv('LINES=50');
$terminal = new Terminal();
$terminal->setWidth(100);
$terminal->setHeight(50);
$this->assertSame(100, $terminal->getWidth());
$this->assertSame(50, $terminal->getHeight());
putenv('COLUMNS=120');
putenv('LINES=60');
$terminal = new Terminal();
$this->assertSame(120, $terminal->getWidth());
$this->assertSame(60, $terminal->getHeight());
}
}