From 37774e6b72ae84ba05e8e5e55b31cc363da46acc Mon Sep 17 00:00:00 2001 From: Jaymin G <40832979+jayminsilicon@users.noreply.github.com> Date: Wed, 31 Jan 2024 21:26:55 +0530 Subject: [PATCH 1/6] [Console] Allow false as a $shortcut in InputOption --- Input/InputOption.php | 2 +- Tests/Input/InputOptionTest.php | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Input/InputOption.php b/Input/InputOption.php index 1d8dbca31..99807f59e 100644 --- a/Input/InputOption.php +++ b/Input/InputOption.php @@ -69,7 +69,7 @@ public function __construct(string $name, $shortcut = null, ?int $mode = null, s throw new InvalidArgumentException('An option name cannot be empty.'); } - if ('' === $shortcut || [] === $shortcut) { + if ('' === $shortcut || [] === $shortcut || false === $shortcut) { $shortcut = null; } diff --git a/Tests/Input/InputOptionTest.php b/Tests/Input/InputOptionTest.php index 55a840ac7..83b295fcc 100644 --- a/Tests/Input/InputOptionTest.php +++ b/Tests/Input/InputOptionTest.php @@ -69,6 +69,8 @@ public function testShortcut() $this->assertEquals('0|z', $option->getShortcut(), '-0 is an acceptable shortcut value when embedded in an array'); $option = new InputOption('foo', '0|z'); $this->assertEquals('0|z', $option->getShortcut(), '-0 is an acceptable shortcut value when embedded in a string-list'); + $option = new InputOption('foo', false); + $this->assertNull($option->getShortcut(), '__construct() makes the shortcut null when given a false as value'); } public function testModes() From d7c327c061094fb4d22791614263944dcabd38c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= Date: Wed, 31 Jan 2024 15:46:24 +0100 Subject: [PATCH 2/6] [Console] Fix color support --- Output/StreamOutput.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Output/StreamOutput.php b/Output/StreamOutput.php index 0ef15cf31..595ac7fd9 100644 --- a/Output/StreamOutput.php +++ b/Output/StreamOutput.php @@ -106,10 +106,22 @@ protected function hasColorSupport() return true; } - return 'Hyper' === getenv('TERM_PROGRAM') + if ('Hyper' === getenv('TERM_PROGRAM') + || false !== getenv('COLORTERM') || false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI') - || str_starts_with((string) getenv('TERM'), 'xterm'); + ) { + return true; + } + + $term = (string) getenv('TERM'); + + if ('dumb' === $term) { + return false; + } + + // See https://github.com/chalk/supports-color/blob/d4f413efaf8da045c5ab440ed418ef02dbb28bf1/index.js#L157 + return 1 === @preg_match('/^((screen|xterm|vt100|vt220|putty|rxvt|ansi|cygwin|linux).*)|(.*-256(color)?(-bce)?)$/', $term); } /** From f5436ad1cced14139c458775323bed607e530dc6 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 5 Feb 2024 17:03:04 +0100 Subject: [PATCH 3/6] [VarDumper][PhpUnitBridge] Fix color detection --- Helper/QuestionHelper.php | 14 +------------- Output/StreamOutput.php | 26 ++++---------------------- 2 files changed, 5 insertions(+), 35 deletions(-) diff --git a/Helper/QuestionHelper.php b/Helper/QuestionHelper.php index e236be92a..7b9de9229 100644 --- a/Helper/QuestionHelper.php +++ b/Helper/QuestionHelper.php @@ -503,19 +503,7 @@ private function isInteractiveInput($inputStream): bool return self::$stdinIsInteractive; } - if (\function_exists('stream_isatty')) { - return self::$stdinIsInteractive = @stream_isatty(fopen('php://stdin', 'r')); - } - - if (\function_exists('posix_isatty')) { - return self::$stdinIsInteractive = @posix_isatty(fopen('php://stdin', 'r')); - } - - if (!\function_exists('shell_exec')) { - return self::$stdinIsInteractive = true; - } - - return self::$stdinIsInteractive = (bool) shell_exec('stty 2> '.('\\' === \DIRECTORY_SEPARATOR ? 'NUL' : '/dev/null')); + return self::$stdinIsInteractive = @stream_isatty(fopen('php://stdin', 'r')); } /** diff --git a/Output/StreamOutput.php b/Output/StreamOutput.php index 595ac7fd9..95dc00a44 100644 --- a/Output/StreamOutput.php +++ b/Output/StreamOutput.php @@ -99,10 +99,7 @@ protected function hasColorSupport() return false; } - if (\DIRECTORY_SEPARATOR === '\\' - && \function_exists('sapi_windows_vt100_support') - && @sapi_windows_vt100_support($this->stream) - ) { + if ('\\' === \DIRECTORY_SEPARATOR && @sapi_windows_vt100_support($this->stream)) { return true; } @@ -114,14 +111,12 @@ protected function hasColorSupport() return true; } - $term = (string) getenv('TERM'); - - if ('dumb' === $term) { + if ('dumb' === $term = (string) getenv('TERM')) { return false; } // See https://github.com/chalk/supports-color/blob/d4f413efaf8da045c5ab440ed418ef02dbb28bf1/index.js#L157 - return 1 === @preg_match('/^((screen|xterm|vt100|vt220|putty|rxvt|ansi|cygwin|linux).*)|(.*-256(color)?(-bce)?)$/', $term); + return preg_match('/^((screen|xterm|vt100|vt220|putty|rxvt|ansi|cygwin|linux).*)|(.*-256(color)?(-bce)?)$/', $term); } /** @@ -138,19 +133,6 @@ private function isTty(): bool return true; } - // Modern cross-platform function, includes the fstat fallback so if it is present we trust it - if (\function_exists('stream_isatty')) { - return stream_isatty($this->stream); - } - - // Only trusting this if it is positive, otherwise prefer fstat fallback. - if (\function_exists('posix_isatty') && posix_isatty($this->stream)) { - return true; - } - - $stat = @fstat($this->stream); - - // Check if formatted mode is S_IFCHR - return $stat ? 0020000 === ($stat['mode'] & 0170000) : false; + return @stream_isatty($this->stream); } } From 8ec305a83aae199c0c08f4317e5b9b1894539fba Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 8 Feb 2024 08:18:31 +0100 Subject: [PATCH 4/6] [PhpUnitBridge][VarDumper] fix color detection --- Output/StreamOutput.php | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/Output/StreamOutput.php b/Output/StreamOutput.php index 95dc00a44..5f5ffce32 100644 --- a/Output/StreamOutput.php +++ b/Output/StreamOutput.php @@ -95,7 +95,9 @@ protected function hasColorSupport() return false; } - if (!$this->isTty()) { + // Detect msysgit/mingw and assume this is a tty because detection + // does not work correctly, see https://github.com/composer/composer/issues/9690 + if (!@stream_isatty($this->stream) && !\in_array(strtoupper((string) getenv('MSYSTEM')), ['MINGW32', 'MINGW64'], true)) { return false; } @@ -118,21 +120,4 @@ protected function hasColorSupport() // See https://github.com/chalk/supports-color/blob/d4f413efaf8da045c5ab440ed418ef02dbb28bf1/index.js#L157 return preg_match('/^((screen|xterm|vt100|vt220|putty|rxvt|ansi|cygwin|linux).*)|(.*-256(color)?(-bce)?)$/', $term); } - - /** - * Checks if the stream is a TTY, i.e; whether the output stream is connected to a terminal. - * - * Reference: Composer\Util\Platform::isTty - * https://github.com/composer/composer - */ - private function isTty(): bool - { - // Detect msysgit/mingw and assume this is a tty because detection - // does not work correctly, see https://github.com/composer/composer/issues/9690 - if (\in_array(strtoupper((string) getenv('MSYSTEM')), ['MINGW32', 'MINGW64'], true)) { - return true; - } - - return @stream_isatty($this->stream); - } } From 155f2f3067ff61b635d80cff6d1580e3a9baf6e2 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Tue, 20 Feb 2024 14:10:45 +0100 Subject: [PATCH 5/6] Fix vertical table on windows --- Helper/Table.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Helper/Table.php b/Helper/Table.php index a7e3fa250..f2c386e17 100644 --- a/Helper/Table.php +++ b/Helper/Table.php @@ -365,7 +365,8 @@ public function render() for ($i = 0; $i < $maxRows; ++$i) { $cell = (string) ($row[$i] ?? ''); - $parts = explode("\n", $cell); + $eol = str_contains($cell, "\r\n") ? "\r\n" : "\n"; + $parts = explode($eol, $cell); foreach ($parts as $idx => $part) { if ($headers && !$containsColspan) { if (0 === $idx) { From 39f75d9d73d0c11952fdcecf4877b4d0f62a8f6e Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Mon, 19 Feb 2024 18:56:30 +0100 Subject: [PATCH 6/6] [Console] Fix display of Table on Windows OS --- Helper/Table.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Helper/Table.php b/Helper/Table.php index 408a76d67..698f9693b 100644 --- a/Helper/Table.php +++ b/Helper/Table.php @@ -621,9 +621,10 @@ private function buildTableRows(array $rows): TableRows if (!strstr($cell ?? '', "\n")) { continue; } - $escaped = implode("\n", array_map([OutputFormatter::class, 'escapeTrailingBackslash'], explode("\n", $cell))); + $eol = str_contains($cell ?? '', "\r\n") ? "\r\n" : "\n"; + $escaped = implode($eol, array_map([OutputFormatter::class, 'escapeTrailingBackslash'], explode($eol, $cell))); $cell = $cell instanceof TableCell ? new TableCell($escaped, ['colspan' => $cell->getColspan()]) : $escaped; - $lines = explode("\n", str_replace("\n", "\n", $cell)); + $lines = explode($eol, str_replace($eol, ''.$eol, $cell)); foreach ($lines as $lineKey => $line) { if ($colspan > 1) { $line = new TableCell($line, ['colspan' => $colspan]); @@ -685,8 +686,9 @@ private function fillNextRows(array $rows, int $line): array $nbLines = $cell->getRowspan() - 1; $lines = [$cell]; if (strstr($cell, "\n")) { - $lines = explode("\n", str_replace("\n", "\n", $cell)); - $nbLines = \count($lines) > $nbLines ? substr_count($cell, "\n") : $nbLines; + $eol = str_contains($cell, "\r\n") ? "\r\n" : "\n"; + $lines = explode($eol, str_replace($eol, ''.$eol.'', $cell)); + $nbLines = \count($lines) > $nbLines ? substr_count($cell, $eol) : $nbLines; $rows[$line][$column] = new TableCell($lines[0], ['colspan' => $cell->getColspan(), 'style' => $cell->getStyle()]); unset($lines[0]);