annotate vendor/sebastian/environment/src/Console.php @ 5:12f9dff5fda9 tip

Update to Drupal core 8.7.1
author Chris Cannam
date Thu, 09 May 2019 15:34:47 +0100
parents 5311817fb629
children
rev   line source
Chris@0 1 <?php
Chris@0 2 /*
Chris@2 3 * This file is part of sebastian/environment.
Chris@0 4 *
Chris@0 5 * (c) Sebastian Bergmann <sebastian@phpunit.de>
Chris@0 6 *
Chris@0 7 * For the full copyright and license information, please view the LICENSE
Chris@0 8 * file that was distributed with this source code.
Chris@0 9 */
Chris@0 10
Chris@2 11 declare(strict_types=1);
Chris@2 12
Chris@0 13 namespace SebastianBergmann\Environment;
Chris@0 14
Chris@2 15 final class Console
Chris@0 16 {
Chris@2 17 /**
Chris@2 18 * @var int
Chris@2 19 */
Chris@0 20 const STDIN = 0;
Chris@2 21
Chris@2 22 /**
Chris@2 23 * @var int
Chris@2 24 */
Chris@0 25 const STDOUT = 1;
Chris@2 26
Chris@2 27 /**
Chris@2 28 * @var int
Chris@2 29 */
Chris@0 30 const STDERR = 2;
Chris@0 31
Chris@0 32 /**
Chris@0 33 * Returns true if STDOUT supports colorization.
Chris@0 34 *
Chris@0 35 * This code has been copied and adapted from
Chris@0 36 * Symfony\Component\Console\Output\OutputStream.
Chris@0 37 */
Chris@2 38 public function hasColorSupport(): bool
Chris@0 39 {
Chris@2 40 if ($this->isWindows()) {
Chris@2 41 // @codeCoverageIgnoreStart
Chris@2 42 return false !== \getenv('ANSICON') || 'ON' === \getenv('ConEmuANSI') || 'xterm' === \getenv('TERM');
Chris@2 43 // @codeCoverageIgnoreEnd
Chris@0 44 }
Chris@0 45
Chris@2 46 if (!\defined('STDOUT')) {
Chris@2 47 // @codeCoverageIgnoreStart
Chris@0 48 return false;
Chris@2 49 // @codeCoverageIgnoreEnd
Chris@0 50 }
Chris@0 51
Chris@0 52 return $this->isInteractive(STDOUT);
Chris@0 53 }
Chris@0 54
Chris@0 55 /**
Chris@0 56 * Returns the number of columns of the terminal.
Chris@0 57 *
Chris@2 58 * @codeCoverageIgnore
Chris@0 59 */
Chris@2 60 public function getNumberOfColumns(): int
Chris@0 61 {
Chris@2 62 if ($this->isWindows()) {
Chris@2 63 return $this->getNumberOfColumnsWindows();
Chris@0 64 }
Chris@0 65
Chris@0 66 if (!$this->isInteractive(self::STDIN)) {
Chris@0 67 return 80;
Chris@0 68 }
Chris@0 69
Chris@2 70 return $this->getNumberOfColumnsInteractive();
Chris@2 71 }
Chris@2 72
Chris@2 73 /**
Chris@2 74 * Returns if the file descriptor is an interactive terminal or not.
Chris@2 75 *
Chris@2 76 * @param int|resource $fileDescriptor
Chris@2 77 */
Chris@2 78 public function isInteractive($fileDescriptor = self::STDOUT): bool
Chris@2 79 {
Chris@2 80 return \function_exists('posix_isatty') && @\posix_isatty($fileDescriptor);
Chris@2 81 }
Chris@2 82
Chris@2 83 private function isWindows(): bool
Chris@2 84 {
Chris@2 85 return DIRECTORY_SEPARATOR === '\\';
Chris@2 86 }
Chris@2 87
Chris@2 88 /**
Chris@2 89 * @codeCoverageIgnore
Chris@2 90 */
Chris@2 91 private function getNumberOfColumnsInteractive(): int
Chris@2 92 {
Chris@2 93 if (\function_exists('shell_exec') && \preg_match('#\d+ (\d+)#', \shell_exec('stty size') ?? '', $match) === 1) {
Chris@0 94 if ((int) $match[1] > 0) {
Chris@0 95 return (int) $match[1];
Chris@0 96 }
Chris@0 97 }
Chris@0 98
Chris@2 99 if (\function_exists('shell_exec') && \preg_match('#columns = (\d+);#', \shell_exec('stty') ?? '', $match) === 1) {
Chris@0 100 if ((int) $match[1] > 0) {
Chris@0 101 return (int) $match[1];
Chris@0 102 }
Chris@0 103 }
Chris@0 104
Chris@0 105 return 80;
Chris@0 106 }
Chris@0 107
Chris@0 108 /**
Chris@2 109 * @codeCoverageIgnore
Chris@0 110 */
Chris@2 111 private function getNumberOfColumnsWindows(): int
Chris@0 112 {
Chris@2 113 $ansicon = \getenv('ANSICON');
Chris@2 114 $columns = 80;
Chris@2 115
Chris@2 116 if (\is_string($ansicon) && \preg_match('/^(\d+)x\d+ \(\d+x(\d+)\)$/', \trim($ansicon), $matches)) {
Chris@2 117 $columns = $matches[1];
Chris@2 118 } elseif (\function_exists('proc_open')) {
Chris@2 119 $process = \proc_open(
Chris@2 120 'mode CON',
Chris@2 121 [
Chris@2 122 1 => ['pipe', 'w'],
Chris@2 123 2 => ['pipe', 'w']
Chris@2 124 ],
Chris@2 125 $pipes,
Chris@2 126 null,
Chris@2 127 null,
Chris@2 128 ['suppress_errors' => true]
Chris@2 129 );
Chris@2 130
Chris@2 131 if (\is_resource($process)) {
Chris@2 132 $info = \stream_get_contents($pipes[1]);
Chris@2 133
Chris@2 134 \fclose($pipes[1]);
Chris@2 135 \fclose($pipes[2]);
Chris@2 136 \proc_close($process);
Chris@2 137
Chris@2 138 if (\preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) {
Chris@2 139 $columns = $matches[2];
Chris@2 140 }
Chris@2 141 }
Chris@2 142 }
Chris@2 143
Chris@2 144 return $columns - 1;
Chris@0 145 }
Chris@0 146 }