Upgrade framework

This commit is contained in:
2023-11-14 16:54:35 +01:00
parent 1648a5cd42
commit 4fcf6fffcc
10548 changed files with 693138 additions and 466698 deletions

View File

@@ -16,17 +16,12 @@ namespace Symfony\Component\Console\Output;
*/
class BufferedOutput extends Output
{
/**
* @var string
*/
private $buffer = '';
private string $buffer = '';
/**
* Empties buffer and returns its content.
*
* @return string
*/
public function fetch()
public function fetch(): string
{
$content = $this->buffer;
$this->buffer = '';
@@ -37,12 +32,12 @@ class BufferedOutput extends Output
/**
* {@inheritdoc}
*/
protected function doWrite($message, $newline)
protected function doWrite(string $message, bool $newline)
{
$this->buffer .= $message;
if ($newline) {
$this->buffer .= PHP_EOL;
$this->buffer .= \PHP_EOL;
}
}
}

View File

@@ -29,22 +29,25 @@ use Symfony\Component\Console\Formatter\OutputFormatterInterface;
*/
class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
{
/**
* @var StreamOutput
*/
private $stderr;
private array $consoleSectionOutputs = [];
/**
* Constructor.
*
* @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
* @param bool|null $decorated Whether to decorate messages (null for auto-guessing)
* @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
*/
public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
public function __construct(int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = null, OutputFormatterInterface $formatter = null)
{
parent::__construct($this->openOutputStream(), $verbosity, $decorated, $formatter);
if (null === $formatter) {
// for BC reasons, stdErr has it own Formatter only when user don't inject a specific formatter.
$this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated);
return;
}
$actualDecorated = $this->isDecorated();
$this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated, $this->getFormatter());
@@ -53,10 +56,18 @@ class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
}
}
/**
* Creates a new output section.
*/
public function section(): ConsoleSectionOutput
{
return new ConsoleSectionOutput($this->getStream(), $this->consoleSectionOutputs, $this->getVerbosity(), $this->isDecorated(), $this->getFormatter());
}
/**
* {@inheritdoc}
*/
public function setDecorated($decorated)
public function setDecorated(bool $decorated)
{
parent::setDecorated($decorated);
$this->stderr->setDecorated($decorated);
@@ -74,7 +85,7 @@ class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
/**
* {@inheritdoc}
*/
public function setVerbosity($level)
public function setVerbosity(int $level)
{
parent::setVerbosity($level);
$this->stderr->setVerbosity($level);
@@ -83,7 +94,7 @@ class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
/**
* {@inheritdoc}
*/
public function getErrorOutput()
public function getErrorOutput(): OutputInterface
{
return $this->stderr;
}
@@ -99,10 +110,8 @@ class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
/**
* Returns true if current environment supports writing console output to
* STDOUT.
*
* @return bool
*/
protected function hasStdoutSupport()
protected function hasStdoutSupport(): bool
{
return false === $this->isRunningOS400();
}
@@ -110,10 +119,8 @@ class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
/**
* Returns true if current environment supports writing console output to
* STDERR.
*
* @return bool
*/
protected function hasStderrSupport()
protected function hasStderrSupport(): bool
{
return false === $this->isRunningOS400();
}
@@ -121,16 +128,14 @@ class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
/**
* Checks if current executing environment is IBM iSeries (OS400), which
* doesn't properly convert character-encodings between ASCII to EBCDIC.
*
* @return bool
*/
private function isRunningOS400()
private function isRunningOS400(): bool
{
$checks = array(
function_exists('php_uname') ? php_uname('s') : '',
$checks = [
\function_exists('php_uname') ? php_uname('s') : '',
getenv('OSTYPE'),
PHP_OS,
);
\PHP_OS,
];
return false !== stripos(implode(';', $checks), 'OS400');
}
@@ -144,7 +149,8 @@ class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
return fopen('php://output', 'w');
}
return @fopen('php://stdout', 'w') ?: fopen('php://output', 'w');
// Use STDOUT when possible to prevent from opening too many file descriptors
return \defined('STDOUT') ? \STDOUT : (@fopen('php://stdout', 'w') ?: fopen('php://output', 'w'));
}
/**
@@ -152,6 +158,11 @@ class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
*/
private function openErrorStream()
{
return fopen($this->hasStderrSupport() ? 'php://stderr' : 'php://output', 'w');
if (!$this->hasStderrSupport()) {
return fopen('php://output', 'w');
}
// Use STDERR when possible to prevent from opening too many file descriptors
return \defined('STDERR') ? \STDERR : (@fopen('php://stderr', 'w') ?: fopen('php://output', 'w'));
}
}

View File

@@ -13,7 +13,7 @@ namespace Symfony\Component\Console\Output;
/**
* ConsoleOutputInterface is the interface implemented by ConsoleOutput class.
* This adds information about stderr output stream.
* This adds information about stderr and section output stream.
*
* @author Dariusz Górecki <darek.krk@gmail.com>
*/
@@ -21,15 +21,10 @@ interface ConsoleOutputInterface extends OutputInterface
{
/**
* Gets the OutputInterface for errors.
*
* @return OutputInterface
*/
public function getErrorOutput();
public function getErrorOutput(): OutputInterface;
/**
* Sets the OutputInterface used for errors.
*
* @param OutputInterface $error
*/
public function setErrorOutput(OutputInterface $error);
public function section(): ConsoleSectionOutput;
}

View File

@@ -0,0 +1,141 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Console\Output;
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Terminal;
/**
* @author Pierre du Plessis <pdples@gmail.com>
* @author Gabriel Ostrolucký <gabriel.ostrolucky@gmail.com>
*/
class ConsoleSectionOutput extends StreamOutput
{
private array $content = [];
private int $lines = 0;
private array $sections;
private $terminal;
/**
* @param resource $stream
* @param ConsoleSectionOutput[] $sections
*/
public function __construct($stream, array &$sections, int $verbosity, bool $decorated, OutputFormatterInterface $formatter)
{
parent::__construct($stream, $verbosity, $decorated, $formatter);
array_unshift($sections, $this);
$this->sections = &$sections;
$this->terminal = new Terminal();
}
/**
* Clears previous output for this section.
*
* @param int $lines Number of lines to clear. If null, then the entire output of this section is cleared
*/
public function clear(int $lines = null)
{
if (empty($this->content) || !$this->isDecorated()) {
return;
}
if ($lines) {
array_splice($this->content, -($lines * 2)); // Multiply lines by 2 to cater for each new line added between content
} else {
$lines = $this->lines;
$this->content = [];
}
$this->lines -= $lines;
parent::doWrite($this->popStreamContentUntilCurrentSection($lines), false);
}
/**
* Overwrites the previous output with a new message.
*/
public function overwrite(string|iterable $message)
{
$this->clear();
$this->writeln($message);
}
public function getContent(): string
{
return implode('', $this->content);
}
/**
* @internal
*/
public function addContent(string $input)
{
foreach (explode(\PHP_EOL, $input) as $lineContent) {
$this->lines += ceil($this->getDisplayLength($lineContent) / $this->terminal->getWidth()) ?: 1;
$this->content[] = $lineContent;
$this->content[] = \PHP_EOL;
}
}
/**
* {@inheritdoc}
*/
protected function doWrite(string $message, bool $newline)
{
if (!$this->isDecorated()) {
parent::doWrite($message, $newline);
return;
}
$erasedContent = $this->popStreamContentUntilCurrentSection();
$this->addContent($message);
parent::doWrite($message, true);
parent::doWrite($erasedContent, false);
}
/**
* At initial stage, cursor is at the end of stream output. This method makes cursor crawl upwards until it hits
* current section. Then it erases content it crawled through. Optionally, it erases part of current section too.
*/
private function popStreamContentUntilCurrentSection(int $numberOfLinesToClearFromCurrentSection = 0): string
{
$numberOfLinesToClear = $numberOfLinesToClearFromCurrentSection;
$erasedContent = [];
foreach ($this->sections as $section) {
if ($section === $this) {
break;
}
$numberOfLinesToClear += $section->lines;
$erasedContent[] = $section->getContent();
}
if ($numberOfLinesToClear > 0) {
// move cursor up n lines
parent::doWrite(sprintf("\x1b[%dA", $numberOfLinesToClear), false);
// erase to end of screen
parent::doWrite("\x1b[0J", false);
}
return implode('', array_reverse($erasedContent));
}
private function getDisplayLength(string $text): int
{
return Helper::width(Helper::removeDecoration($this->getFormatter(), str_replace("\t", ' ', $text)));
}
}

View File

@@ -11,7 +11,7 @@
namespace Symfony\Component\Console\Output;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Formatter\NullOutputFormatter;
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
/**
@@ -24,6 +24,8 @@ use Symfony\Component\Console\Formatter\OutputFormatterInterface;
*/
class NullOutput implements OutputInterface
{
private $formatter;
/**
* {@inheritdoc}
*/
@@ -35,16 +37,16 @@ class NullOutput implements OutputInterface
/**
* {@inheritdoc}
*/
public function getFormatter()
public function getFormatter(): OutputFormatterInterface
{
// to comply with the interface we must return a OutputFormatterInterface
return new OutputFormatter();
return $this->formatter ??= new NullOutputFormatter();
}
/**
* {@inheritdoc}
*/
public function setDecorated($decorated)
public function setDecorated(bool $decorated)
{
// do nothing
}
@@ -52,7 +54,7 @@ class NullOutput implements OutputInterface
/**
* {@inheritdoc}
*/
public function isDecorated()
public function isDecorated(): bool
{
return false;
}
@@ -60,7 +62,7 @@ class NullOutput implements OutputInterface
/**
* {@inheritdoc}
*/
public function setVerbosity($level)
public function setVerbosity(int $level)
{
// do nothing
}
@@ -68,7 +70,7 @@ class NullOutput implements OutputInterface
/**
* {@inheritdoc}
*/
public function getVerbosity()
public function getVerbosity(): int
{
return self::VERBOSITY_QUIET;
}
@@ -76,7 +78,7 @@ class NullOutput implements OutputInterface
/**
* {@inheritdoc}
*/
public function isQuiet()
public function isQuiet(): bool
{
return true;
}
@@ -84,7 +86,7 @@ class NullOutput implements OutputInterface
/**
* {@inheritdoc}
*/
public function isVerbose()
public function isVerbose(): bool
{
return false;
}
@@ -92,7 +94,7 @@ class NullOutput implements OutputInterface
/**
* {@inheritdoc}
*/
public function isVeryVerbose()
public function isVeryVerbose(): bool
{
return false;
}
@@ -100,7 +102,7 @@ class NullOutput implements OutputInterface
/**
* {@inheritdoc}
*/
public function isDebug()
public function isDebug(): bool
{
return false;
}
@@ -108,7 +110,7 @@ class NullOutput implements OutputInterface
/**
* {@inheritdoc}
*/
public function writeln($messages, $options = self::OUTPUT_NORMAL)
public function writeln(string|iterable $messages, int $options = self::OUTPUT_NORMAL)
{
// do nothing
}
@@ -116,7 +118,7 @@ class NullOutput implements OutputInterface
/**
* {@inheritdoc}
*/
public function write($messages, $newline = false, $options = self::OUTPUT_NORMAL)
public function write(string|iterable $messages, bool $newline = false, int $options = self::OUTPUT_NORMAL)
{
// do nothing
}

View File

@@ -11,8 +11,8 @@
namespace Symfony\Component\Console\Output;
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
/**
* Base class for output classes.
@@ -29,20 +29,18 @@ use Symfony\Component\Console\Formatter\OutputFormatter;
*/
abstract class Output implements OutputInterface
{
private $verbosity;
private int $verbosity;
private $formatter;
/**
* Constructor.
*
* @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
* @param int|null $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
* @param bool $decorated Whether to decorate messages
* @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
*/
public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = false, OutputFormatterInterface $formatter = null)
public function __construct(?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = false, OutputFormatterInterface $formatter = null)
{
$this->verbosity = null === $verbosity ? self::VERBOSITY_NORMAL : $verbosity;
$this->formatter = $formatter ?: new OutputFormatter();
$this->verbosity = $verbosity ?? self::VERBOSITY_NORMAL;
$this->formatter = $formatter ?? new OutputFormatter();
$this->formatter->setDecorated($decorated);
}
@@ -57,7 +55,7 @@ abstract class Output implements OutputInterface
/**
* {@inheritdoc}
*/
public function getFormatter()
public function getFormatter(): OutputFormatterInterface
{
return $this->formatter;
}
@@ -65,7 +63,7 @@ abstract class Output implements OutputInterface
/**
* {@inheritdoc}
*/
public function setDecorated($decorated)
public function setDecorated(bool $decorated)
{
$this->formatter->setDecorated($decorated);
}
@@ -73,7 +71,7 @@ abstract class Output implements OutputInterface
/**
* {@inheritdoc}
*/
public function isDecorated()
public function isDecorated(): bool
{
return $this->formatter->isDecorated();
}
@@ -81,15 +79,15 @@ abstract class Output implements OutputInterface
/**
* {@inheritdoc}
*/
public function setVerbosity($level)
public function setVerbosity(int $level)
{
$this->verbosity = (int) $level;
$this->verbosity = $level;
}
/**
* {@inheritdoc}
*/
public function getVerbosity()
public function getVerbosity(): int
{
return $this->verbosity;
}
@@ -97,7 +95,7 @@ abstract class Output implements OutputInterface
/**
* {@inheritdoc}
*/
public function isQuiet()
public function isQuiet(): bool
{
return self::VERBOSITY_QUIET === $this->verbosity;
}
@@ -105,7 +103,7 @@ abstract class Output implements OutputInterface
/**
* {@inheritdoc}
*/
public function isVerbose()
public function isVerbose(): bool
{
return self::VERBOSITY_VERBOSE <= $this->verbosity;
}
@@ -113,7 +111,7 @@ abstract class Output implements OutputInterface
/**
* {@inheritdoc}
*/
public function isVeryVerbose()
public function isVeryVerbose(): bool
{
return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity;
}
@@ -121,7 +119,7 @@ abstract class Output implements OutputInterface
/**
* {@inheritdoc}
*/
public function isDebug()
public function isDebug(): bool
{
return self::VERBOSITY_DEBUG <= $this->verbosity;
}
@@ -129,7 +127,7 @@ abstract class Output implements OutputInterface
/**
* {@inheritdoc}
*/
public function writeln($messages, $options = self::OUTPUT_NORMAL)
public function writeln(string|iterable $messages, int $options = self::OUTPUT_NORMAL)
{
$this->write($messages, true, $options);
}
@@ -137,9 +135,11 @@ abstract class Output implements OutputInterface
/**
* {@inheritdoc}
*/
public function write($messages, $newline = false, $options = self::OUTPUT_NORMAL)
public function write(string|iterable $messages, bool $newline = false, int $options = self::OUTPUT_NORMAL)
{
$messages = (array) $messages;
if (!is_iterable($messages)) {
$messages = [$messages];
}
$types = self::OUTPUT_NORMAL | self::OUTPUT_RAW | self::OUTPUT_PLAIN;
$type = $types & $options ?: self::OUTPUT_NORMAL;
@@ -163,15 +163,12 @@ abstract class Output implements OutputInterface
break;
}
$this->doWrite($message, $newline);
$this->doWrite($message ?? '', $newline);
}
}
/**
* Writes a message to the output.
*
* @param string $message A message to write to the output
* @param bool $newline Whether to add a newline or not
*/
abstract protected function doWrite($message, $newline);
abstract protected function doWrite(string $message, bool $newline);
}

View File

@@ -20,100 +20,75 @@ use Symfony\Component\Console\Formatter\OutputFormatterInterface;
*/
interface OutputInterface
{
const VERBOSITY_QUIET = 16;
const VERBOSITY_NORMAL = 32;
const VERBOSITY_VERBOSE = 64;
const VERBOSITY_VERY_VERBOSE = 128;
const VERBOSITY_DEBUG = 256;
public const VERBOSITY_QUIET = 16;
public const VERBOSITY_NORMAL = 32;
public const VERBOSITY_VERBOSE = 64;
public const VERBOSITY_VERY_VERBOSE = 128;
public const VERBOSITY_DEBUG = 256;
const OUTPUT_NORMAL = 1;
const OUTPUT_RAW = 2;
const OUTPUT_PLAIN = 4;
public const OUTPUT_NORMAL = 1;
public const OUTPUT_RAW = 2;
public const OUTPUT_PLAIN = 4;
/**
* Writes a message to the output.
*
* @param string|array $messages The message as an array of lines or a single string
* @param bool $newline Whether to add a newline
* @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL
* @param $newline Whether to add a newline
* @param $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL
*/
public function write($messages, $newline = false, $options = 0);
public function write(string|iterable $messages, bool $newline = false, int $options = 0);
/**
* Writes a message to the output and adds a newline at the end.
*
* @param string|array $messages The message as an array of lines of a single string
* @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL
* @param $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL
*/
public function writeln($messages, $options = 0);
public function writeln(string|iterable $messages, int $options = 0);
/**
* Sets the verbosity of the output.
*
* @param int $level The level of verbosity (one of the VERBOSITY constants)
*/
public function setVerbosity($level);
public function setVerbosity(int $level);
/**
* Gets the current verbosity of the output.
*
* @return int The current level of verbosity (one of the VERBOSITY constants)
*/
public function getVerbosity();
public function getVerbosity(): int;
/**
* Returns whether verbosity is quiet (-q).
*
* @return bool true if verbosity is set to VERBOSITY_QUIET, false otherwise
*/
public function isQuiet();
public function isQuiet(): bool;
/**
* Returns whether verbosity is verbose (-v).
*
* @return bool true if verbosity is set to VERBOSITY_VERBOSE, false otherwise
*/
public function isVerbose();
public function isVerbose(): bool;
/**
* Returns whether verbosity is very verbose (-vv).
*
* @return bool true if verbosity is set to VERBOSITY_VERY_VERBOSE, false otherwise
*/
public function isVeryVerbose();
public function isVeryVerbose(): bool;
/**
* Returns whether verbosity is debug (-vvv).
*
* @return bool true if verbosity is set to VERBOSITY_DEBUG, false otherwise
*/
public function isDebug();
public function isDebug(): bool;
/**
* Sets the decorated flag.
*
* @param bool $decorated Whether to decorate the messages
*/
public function setDecorated($decorated);
public function setDecorated(bool $decorated);
/**
* Gets the decorated flag.
*
* @return bool true if the output will decorate messages, false otherwise
*/
public function isDecorated();
public function isDecorated(): bool;
/**
* Sets output formatter.
*
* @param OutputFormatterInterface $formatter
*/
public function setFormatter(OutputFormatterInterface $formatter);
/**
* Returns current output formatter instance.
*
* @return OutputFormatterInterface
*/
public function getFormatter();
public function getFormatter(): OutputFormatterInterface;
}

View File

@@ -12,7 +12,6 @@
namespace Symfony\Component\Console\Output;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
/**
@@ -20,11 +19,11 @@ use Symfony\Component\Console\Formatter\OutputFormatterInterface;
*
* Usage:
*
* $output = new StreamOutput(fopen('php://stdout', 'w'));
* $output = new StreamOutput(fopen('php://stdout', 'w'));
*
* As `StreamOutput` can use any stream, you can also use a file:
*
* $output = new StreamOutput(fopen('/path/to/output.log', 'a', false));
* $output = new StreamOutput(fopen('/path/to/output.log', 'a', false));
*
* @author Fabien Potencier <fabien@symfony.com>
*/
@@ -33,8 +32,6 @@ class StreamOutput extends Output
private $stream;
/**
* Constructor.
*
* @param resource $stream A stream resource
* @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
* @param bool|null $decorated Whether to decorate messages (null for auto-guessing)
@@ -42,9 +39,9 @@ class StreamOutput extends Output
*
* @throws InvalidArgumentException When first argument is not a real stream
*/
public function __construct($stream, $verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
public function __construct($stream, int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = null, OutputFormatterInterface $formatter = null)
{
if (!is_resource($stream) || 'stream' !== get_resource_type($stream)) {
if (!\is_resource($stream) || 'stream' !== get_resource_type($stream)) {
throw new InvalidArgumentException('The StreamOutput class needs a stream as its first argument.');
}
@@ -60,7 +57,7 @@ class StreamOutput extends Output
/**
* Gets the stream attached to this StreamOutput instance.
*
* @return resource A stream resource
* @return resource
*/
public function getStream()
{
@@ -70,13 +67,14 @@ class StreamOutput extends Output
/**
* {@inheritdoc}
*/
protected function doWrite($message, $newline)
protected function doWrite(string $message, bool $newline)
{
if (false === @fwrite($this->stream, $message) || ($newline && (false === @fwrite($this->stream, PHP_EOL)))) {
// should never happen
throw new RuntimeException('Unable to write output.');
if ($newline) {
$message .= \PHP_EOL;
}
@fwrite($this->stream, $message);
fflush($this->stream);
}
@@ -85,21 +83,33 @@ class StreamOutput extends Output
*
* Colorization is disabled if not supported by the stream:
*
* - Windows != 10.0.10586 without Ansicon, ConEmu or Mintty
* - non tty consoles
* This is tricky on Windows, because Cygwin, Msys2 etc emulate pseudo
* terminals via named pipes, so we can only check the environment.
*
* Reference: Composer\XdebugHandler\Process::supportsColor
* https://github.com/composer/xdebug-handler
*
* @return bool true if the stream supports colorization, false otherwise
*/
protected function hasColorSupport()
protected function hasColorSupport(): bool
{
if (DIRECTORY_SEPARATOR === '\\') {
return
'10.0.10586' === PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD
// Follow https://no-color.org/
if (isset($_SERVER['NO_COLOR']) || false !== getenv('NO_COLOR')) {
return false;
}
if ('Hyper' === getenv('TERM_PROGRAM')) {
return true;
}
if (\DIRECTORY_SEPARATOR === '\\') {
return (\function_exists('sapi_windows_vt100_support')
&& @sapi_windows_vt100_support($this->stream))
|| false !== getenv('ANSICON')
|| 'ON' === getenv('ConEmuANSI')
|| 'xterm' === getenv('TERM');
}
return function_exists('posix_isatty') && @posix_isatty($this->stream);
return stream_isatty($this->stream);
}
}

View File

@@ -0,0 +1,61 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Console\Output;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
/**
* A BufferedOutput that keeps only the last N chars.
*
* @author Jérémy Derussé <jeremy@derusse.com>
*/
class TrimmedBufferOutput extends Output
{
private int $maxLength;
private string $buffer = '';
public function __construct(int $maxLength, ?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = false, OutputFormatterInterface $formatter = null)
{
if ($maxLength <= 0) {
throw new InvalidArgumentException(sprintf('"%s()" expects a strictly positive maxLength. Got %d.', __METHOD__, $maxLength));
}
parent::__construct($verbosity, $decorated, $formatter);
$this->maxLength = $maxLength;
}
/**
* Empties buffer and returns its content.
*/
public function fetch(): string
{
$content = $this->buffer;
$this->buffer = '';
return $content;
}
/**
* {@inheritdoc}
*/
protected function doWrite(string $message, bool $newline)
{
$this->buffer .= $message;
if ($newline) {
$this->buffer .= \PHP_EOL;
}
$this->buffer = substr($this->buffer, 0 - $this->maxLength);
}
}