first commit
This commit is contained in:
106
vendor/symfony/console/Output/AnsiColorMode.php
vendored
Normal file
106
vendor/symfony/console/Output/AnsiColorMode.php
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Julien Boudry <julien@condorcet.vote>
|
||||
*/
|
||||
enum AnsiColorMode
|
||||
{
|
||||
/*
|
||||
* Classical 4-bit Ansi colors, including 8 classical colors and 8 bright color. Output syntax is "ESC[${foreGroundColorcode};${backGroundColorcode}m"
|
||||
* Must be compatible with all terminals and it's the minimal version supported.
|
||||
*/
|
||||
case Ansi4;
|
||||
|
||||
/*
|
||||
* 8-bit Ansi colors (240 different colors + 16 duplicate color codes, ensuring backward compatibility).
|
||||
* Output syntax is: "ESC[38;5;${foreGroundColorcode};48;5;${backGroundColorcode}m"
|
||||
* Should be compatible with most terminals.
|
||||
*/
|
||||
case Ansi8;
|
||||
|
||||
/*
|
||||
* 24-bit Ansi colors (RGB).
|
||||
* Output syntax is: "ESC[38;2;${foreGroundColorcodeRed};${foreGroundColorcodeGreen};${foreGroundColorcodeBlue};48;2;${backGroundColorcodeRed};${backGroundColorcodeGreen};${backGroundColorcodeBlue}m"
|
||||
* May be compatible with many modern terminals.
|
||||
*/
|
||||
case Ansi24;
|
||||
|
||||
/**
|
||||
* Converts an RGB hexadecimal color to the corresponding Ansi code.
|
||||
*/
|
||||
public function convertFromHexToAnsiColorCode(string $hexColor): string
|
||||
{
|
||||
$hexColor = str_replace('#', '', $hexColor);
|
||||
|
||||
if (3 === \strlen($hexColor)) {
|
||||
$hexColor = $hexColor[0].$hexColor[0].$hexColor[1].$hexColor[1].$hexColor[2].$hexColor[2];
|
||||
}
|
||||
|
||||
if (6 !== \strlen($hexColor)) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid "#%s" color.', $hexColor));
|
||||
}
|
||||
|
||||
$color = hexdec($hexColor);
|
||||
|
||||
$r = ($color >> 16) & 255;
|
||||
$g = ($color >> 8) & 255;
|
||||
$b = $color & 255;
|
||||
|
||||
return match ($this) {
|
||||
self::Ansi4 => (string) $this->convertFromRGB($r, $g, $b),
|
||||
self::Ansi8 => '8;5;'.((string) $this->convertFromRGB($r, $g, $b)),
|
||||
self::Ansi24 => sprintf('8;2;%d;%d;%d', $r, $g, $b)
|
||||
};
|
||||
}
|
||||
|
||||
private function convertFromRGB(int $r, int $g, int $b): int
|
||||
{
|
||||
return match ($this) {
|
||||
self::Ansi4 => $this->degradeHexColorToAnsi4($r, $g, $b),
|
||||
self::Ansi8 => $this->degradeHexColorToAnsi8($r, $g, $b),
|
||||
default => throw new InvalidArgumentException("RGB cannot be converted to {$this->name}.")
|
||||
};
|
||||
}
|
||||
|
||||
private function degradeHexColorToAnsi4(int $r, int $g, int $b): int
|
||||
{
|
||||
return round($b / 255) << 2 | (round($g / 255) << 1) | round($r / 255);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspired from https://github.com/ajalt/colormath/blob/e464e0da1b014976736cf97250063248fc77b8e7/colormath/src/commonMain/kotlin/com/github/ajalt/colormath/model/Ansi256.kt code (MIT license).
|
||||
*/
|
||||
private function degradeHexColorToAnsi8(int $r, int $g, int $b): int
|
||||
{
|
||||
if ($r === $g && $g === $b) {
|
||||
if ($r < 8) {
|
||||
return 16;
|
||||
}
|
||||
|
||||
if ($r > 248) {
|
||||
return 231;
|
||||
}
|
||||
|
||||
return (int) round(($r - 8) / 247 * 24) + 232;
|
||||
} else {
|
||||
return 16 +
|
||||
(36 * (int) round($r / 255 * 5)) +
|
||||
(6 * (int) round($g / 255 * 5)) +
|
||||
(int) round($b / 255 * 5);
|
||||
}
|
||||
}
|
||||
}
|
43
vendor/symfony/console/Output/BufferedOutput.php
vendored
Normal file
43
vendor/symfony/console/Output/BufferedOutput.php
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* @author Jean-François Simon <contact@jfsimon.fr>
|
||||
*/
|
||||
class BufferedOutput extends Output
|
||||
{
|
||||
private string $buffer = '';
|
||||
|
||||
/**
|
||||
* Empties buffer and returns its content.
|
||||
*/
|
||||
public function fetch(): string
|
||||
{
|
||||
$content = $this->buffer;
|
||||
$this->buffer = '';
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doWrite(string $message, bool $newline)
|
||||
{
|
||||
$this->buffer .= $message;
|
||||
|
||||
if ($newline) {
|
||||
$this->buffer .= \PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
165
vendor/symfony/console/Output/ConsoleOutput.php
vendored
Normal file
165
vendor/symfony/console/Output/ConsoleOutput.php
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* ConsoleOutput is the default class for all CLI output. It uses STDOUT and STDERR.
|
||||
*
|
||||
* This class is a convenient wrapper around `StreamOutput` for both STDOUT and STDERR.
|
||||
*
|
||||
* $output = new ConsoleOutput();
|
||||
*
|
||||
* This is equivalent to:
|
||||
*
|
||||
* $output = new StreamOutput(fopen('php://stdout', 'w'));
|
||||
* $stdErr = new StreamOutput(fopen('php://stderr', 'w'));
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
|
||||
{
|
||||
private OutputInterface $stderr;
|
||||
private array $consoleSectionOutputs = [];
|
||||
|
||||
/**
|
||||
* @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(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());
|
||||
|
||||
if (null === $decorated) {
|
||||
$this->setDecorated($actualDecorated && $this->stderr->isDecorated());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new output section.
|
||||
*/
|
||||
public function section(): ConsoleSectionOutput
|
||||
{
|
||||
return new ConsoleSectionOutput($this->getStream(), $this->consoleSectionOutputs, $this->getVerbosity(), $this->isDecorated(), $this->getFormatter());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setDecorated(bool $decorated)
|
||||
{
|
||||
parent::setDecorated($decorated);
|
||||
$this->stderr->setDecorated($decorated);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setFormatter(OutputFormatterInterface $formatter)
|
||||
{
|
||||
parent::setFormatter($formatter);
|
||||
$this->stderr->setFormatter($formatter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setVerbosity(int $level)
|
||||
{
|
||||
parent::setVerbosity($level);
|
||||
$this->stderr->setVerbosity($level);
|
||||
}
|
||||
|
||||
public function getErrorOutput(): OutputInterface
|
||||
{
|
||||
return $this->stderr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setErrorOutput(OutputInterface $error)
|
||||
{
|
||||
$this->stderr = $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if current environment supports writing console output to
|
||||
* STDOUT.
|
||||
*/
|
||||
protected function hasStdoutSupport(): bool
|
||||
{
|
||||
return false === $this->isRunningOS400();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if current environment supports writing console output to
|
||||
* STDERR.
|
||||
*/
|
||||
protected function hasStderrSupport(): bool
|
||||
{
|
||||
return false === $this->isRunningOS400();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if current executing environment is IBM iSeries (OS400), which
|
||||
* doesn't properly convert character-encodings between ASCII to EBCDIC.
|
||||
*/
|
||||
private function isRunningOS400(): bool
|
||||
{
|
||||
$checks = [
|
||||
\function_exists('php_uname') ? php_uname('s') : '',
|
||||
getenv('OSTYPE'),
|
||||
\PHP_OS,
|
||||
];
|
||||
|
||||
return false !== stripos(implode(';', $checks), 'OS400');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return resource
|
||||
*/
|
||||
private function openOutputStream()
|
||||
{
|
||||
if (!$this->hasStdoutSupport()) {
|
||||
return 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'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return resource
|
||||
*/
|
||||
private function openErrorStream()
|
||||
{
|
||||
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'));
|
||||
}
|
||||
}
|
33
vendor/symfony/console/Output/ConsoleOutputInterface.php
vendored
Normal file
33
vendor/symfony/console/Output/ConsoleOutputInterface.php
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* ConsoleOutputInterface is the interface implemented by ConsoleOutput class.
|
||||
* This adds information about stderr and section output stream.
|
||||
*
|
||||
* @author Dariusz Górecki <darek.krk@gmail.com>
|
||||
*/
|
||||
interface ConsoleOutputInterface extends OutputInterface
|
||||
{
|
||||
/**
|
||||
* Gets the OutputInterface for errors.
|
||||
*/
|
||||
public function getErrorOutput(): OutputInterface;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setErrorOutput(OutputInterface $error);
|
||||
|
||||
public function section(): ConsoleSectionOutput;
|
||||
}
|
244
vendor/symfony/console/Output/ConsoleSectionOutput.php
vendored
Normal file
244
vendor/symfony/console/Output/ConsoleSectionOutput.php
vendored
Normal file
@ -0,0 +1,244 @@
|
||||
<?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 $terminal;
|
||||
private int $maxHeight = 0;
|
||||
|
||||
/**
|
||||
* @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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a maximum number of lines for this section.
|
||||
*
|
||||
* When more lines are added, the section will automatically scroll to the
|
||||
* end (i.e. remove the first lines to comply with the max height).
|
||||
*/
|
||||
public function setMaxHeight(int $maxHeight): void
|
||||
{
|
||||
// when changing max height, clear output of current section and redraw again with the new height
|
||||
$previousMaxHeight = $this->maxHeight;
|
||||
$this->maxHeight = $maxHeight;
|
||||
$existingContent = $this->popStreamContentUntilCurrentSection($previousMaxHeight ? min($previousMaxHeight, $this->lines) : $this->lines);
|
||||
|
||||
parent::doWrite($this->getVisibleContent(), false);
|
||||
parent::doWrite($existingContent, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clear(?int $lines = null)
|
||||
{
|
||||
if (empty($this->content) || !$this->isDecorated()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($lines) {
|
||||
array_splice($this->content, -$lines);
|
||||
} else {
|
||||
$lines = $this->lines;
|
||||
$this->content = [];
|
||||
}
|
||||
|
||||
$this->lines -= $lines;
|
||||
|
||||
parent::doWrite($this->popStreamContentUntilCurrentSection($this->maxHeight ? min($this->maxHeight, $lines) : $lines), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites the previous output with a new message.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function overwrite(string|iterable $message)
|
||||
{
|
||||
$this->clear();
|
||||
$this->writeln($message);
|
||||
}
|
||||
|
||||
public function getContent(): string
|
||||
{
|
||||
return implode('', $this->content);
|
||||
}
|
||||
|
||||
public function getVisibleContent(): string
|
||||
{
|
||||
if (0 === $this->maxHeight) {
|
||||
return $this->getContent();
|
||||
}
|
||||
|
||||
return implode('', \array_slice($this->content, -$this->maxHeight));
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function addContent(string $input, bool $newline = true): int
|
||||
{
|
||||
$width = $this->terminal->getWidth();
|
||||
$lines = explode(\PHP_EOL, $input);
|
||||
$linesAdded = 0;
|
||||
$count = \count($lines) - 1;
|
||||
foreach ($lines as $i => $lineContent) {
|
||||
// re-add the line break (that has been removed in the above `explode()` for
|
||||
// - every line that is not the last line
|
||||
// - if $newline is required, also add it to the last line
|
||||
if ($i < $count || $newline) {
|
||||
$lineContent .= \PHP_EOL;
|
||||
}
|
||||
|
||||
// skip line if there is no text (or newline for that matter)
|
||||
if ('' === $lineContent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// For the first line, check if the previous line (last entry of `$this->content`)
|
||||
// needs to be continued (i.e. does not end with a line break).
|
||||
if (0 === $i
|
||||
&& (false !== $lastLine = end($this->content))
|
||||
&& !str_ends_with($lastLine, \PHP_EOL)
|
||||
) {
|
||||
// deduct the line count of the previous line
|
||||
$this->lines -= (int) ceil($this->getDisplayLength($lastLine) / $width) ?: 1;
|
||||
// concatenate previous and new line
|
||||
$lineContent = $lastLine.$lineContent;
|
||||
// replace last entry of `$this->content` with the new expanded line
|
||||
array_splice($this->content, -1, 1, $lineContent);
|
||||
} else {
|
||||
// otherwise just add the new content
|
||||
$this->content[] = $lineContent;
|
||||
}
|
||||
|
||||
$linesAdded += (int) ceil($this->getDisplayLength($lineContent) / $width) ?: 1;
|
||||
}
|
||||
|
||||
$this->lines += $linesAdded;
|
||||
|
||||
return $linesAdded;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function addNewLineOfInputSubmit(): void
|
||||
{
|
||||
$this->content[] = \PHP_EOL;
|
||||
++$this->lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doWrite(string $message, bool $newline)
|
||||
{
|
||||
// Simulate newline behavior for consistent output formatting, avoiding extra logic
|
||||
if (!$newline && str_ends_with($message, \PHP_EOL)) {
|
||||
$message = substr($message, 0, -\strlen(\PHP_EOL));
|
||||
$newline = true;
|
||||
}
|
||||
|
||||
if (!$this->isDecorated()) {
|
||||
parent::doWrite($message, $newline);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the previous line (last entry of `$this->content`) needs to be continued
|
||||
// (i.e. does not end with a line break). In which case, it needs to be erased first.
|
||||
$linesToClear = $deleteLastLine = ($lastLine = end($this->content) ?: '') && !str_ends_with($lastLine, \PHP_EOL) ? 1 : 0;
|
||||
|
||||
$linesAdded = $this->addContent($message, $newline);
|
||||
|
||||
if ($lineOverflow = $this->maxHeight > 0 && $this->lines > $this->maxHeight) {
|
||||
// on overflow, clear the whole section and redraw again (to remove the first lines)
|
||||
$linesToClear = $this->maxHeight;
|
||||
}
|
||||
|
||||
$erasedContent = $this->popStreamContentUntilCurrentSection($linesToClear);
|
||||
|
||||
if ($lineOverflow) {
|
||||
// redraw existing lines of the section
|
||||
$previousLinesOfSection = \array_slice($this->content, $this->lines - $this->maxHeight, $this->maxHeight - $linesAdded);
|
||||
parent::doWrite(implode('', $previousLinesOfSection), false);
|
||||
}
|
||||
|
||||
// if the last line was removed, re-print its content together with the new content.
|
||||
// otherwise, just print the new content.
|
||||
parent::doWrite($deleteLastLine ? $lastLine.$message : $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->maxHeight ? min($section->lines, $section->maxHeight) : $section->lines;
|
||||
if ('' !== $sectionContent = $section->getVisibleContent()) {
|
||||
if (!str_ends_with($sectionContent, \PHP_EOL)) {
|
||||
$sectionContent .= \PHP_EOL;
|
||||
}
|
||||
$erasedContent[] = $sectionContent;
|
||||
}
|
||||
}
|
||||
|
||||
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)));
|
||||
}
|
||||
}
|
104
vendor/symfony/console/Output/NullOutput.php
vendored
Normal file
104
vendor/symfony/console/Output/NullOutput.php
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
<?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\NullOutputFormatter;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
|
||||
|
||||
/**
|
||||
* NullOutput suppresses all output.
|
||||
*
|
||||
* $output = new NullOutput();
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Tobias Schultze <http://tobion.de>
|
||||
*/
|
||||
class NullOutput implements OutputInterface
|
||||
{
|
||||
private NullOutputFormatter $formatter;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setFormatter(OutputFormatterInterface $formatter)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public function getFormatter(): OutputFormatterInterface
|
||||
{
|
||||
// to comply with the interface we must return a OutputFormatterInterface
|
||||
return $this->formatter ??= new NullOutputFormatter();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setDecorated(bool $decorated)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public function isDecorated(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setVerbosity(int $level)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public function getVerbosity(): int
|
||||
{
|
||||
return self::VERBOSITY_QUIET;
|
||||
}
|
||||
|
||||
public function isQuiet(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isVerbose(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isVeryVerbose(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isDebug(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function writeln(string|iterable $messages, int $options = self::OUTPUT_NORMAL)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function write(string|iterable $messages, bool $newline = false, int $options = self::OUTPUT_NORMAL)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
155
vendor/symfony/console/Output/Output.php
vendored
Normal file
155
vendor/symfony/console/Output/Output.php
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
<?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\OutputFormatter;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
|
||||
|
||||
/**
|
||||
* Base class for output classes.
|
||||
*
|
||||
* There are five levels of verbosity:
|
||||
*
|
||||
* * normal: no option passed (normal output)
|
||||
* * verbose: -v (more output)
|
||||
* * very verbose: -vv (highly extended output)
|
||||
* * debug: -vvv (all debug output)
|
||||
* * quiet: -q (no output)
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
abstract class Output implements OutputInterface
|
||||
{
|
||||
private int $verbosity;
|
||||
private OutputFormatterInterface $formatter;
|
||||
|
||||
/**
|
||||
* @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(?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = false, ?OutputFormatterInterface $formatter = null)
|
||||
{
|
||||
$this->verbosity = $verbosity ?? self::VERBOSITY_NORMAL;
|
||||
$this->formatter = $formatter ?? new OutputFormatter();
|
||||
$this->formatter->setDecorated($decorated);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setFormatter(OutputFormatterInterface $formatter)
|
||||
{
|
||||
$this->formatter = $formatter;
|
||||
}
|
||||
|
||||
public function getFormatter(): OutputFormatterInterface
|
||||
{
|
||||
return $this->formatter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setDecorated(bool $decorated)
|
||||
{
|
||||
$this->formatter->setDecorated($decorated);
|
||||
}
|
||||
|
||||
public function isDecorated(): bool
|
||||
{
|
||||
return $this->formatter->isDecorated();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setVerbosity(int $level)
|
||||
{
|
||||
$this->verbosity = $level;
|
||||
}
|
||||
|
||||
public function getVerbosity(): int
|
||||
{
|
||||
return $this->verbosity;
|
||||
}
|
||||
|
||||
public function isQuiet(): bool
|
||||
{
|
||||
return self::VERBOSITY_QUIET === $this->verbosity;
|
||||
}
|
||||
|
||||
public function isVerbose(): bool
|
||||
{
|
||||
return self::VERBOSITY_VERBOSE <= $this->verbosity;
|
||||
}
|
||||
|
||||
public function isVeryVerbose(): bool
|
||||
{
|
||||
return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity;
|
||||
}
|
||||
|
||||
public function isDebug(): bool
|
||||
{
|
||||
return self::VERBOSITY_DEBUG <= $this->verbosity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function writeln(string|iterable $messages, int $options = self::OUTPUT_NORMAL)
|
||||
{
|
||||
$this->write($messages, true, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function write(string|iterable $messages, bool $newline = false, int $options = self::OUTPUT_NORMAL)
|
||||
{
|
||||
if (!is_iterable($messages)) {
|
||||
$messages = [$messages];
|
||||
}
|
||||
|
||||
$types = self::OUTPUT_NORMAL | self::OUTPUT_RAW | self::OUTPUT_PLAIN;
|
||||
$type = $types & $options ?: self::OUTPUT_NORMAL;
|
||||
|
||||
$verbosities = self::VERBOSITY_QUIET | self::VERBOSITY_NORMAL | self::VERBOSITY_VERBOSE | self::VERBOSITY_VERY_VERBOSE | self::VERBOSITY_DEBUG;
|
||||
$verbosity = $verbosities & $options ?: self::VERBOSITY_NORMAL;
|
||||
|
||||
if ($verbosity > $this->getVerbosity()) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($messages as $message) {
|
||||
switch ($type) {
|
||||
case OutputInterface::OUTPUT_NORMAL:
|
||||
$message = $this->formatter->format($message);
|
||||
break;
|
||||
case OutputInterface::OUTPUT_RAW:
|
||||
break;
|
||||
case OutputInterface::OUTPUT_PLAIN:
|
||||
$message = strip_tags($this->formatter->format($message));
|
||||
break;
|
||||
}
|
||||
|
||||
$this->doWrite($message ?? '', $newline);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a message to the output.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function doWrite(string $message, bool $newline);
|
||||
}
|
111
vendor/symfony/console/Output/OutputInterface.php
vendored
Normal file
111
vendor/symfony/console/Output/OutputInterface.php
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* OutputInterface is the interface implemented by all Output classes.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface OutputInterface
|
||||
{
|
||||
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;
|
||||
|
||||
public const OUTPUT_NORMAL = 1;
|
||||
public const OUTPUT_RAW = 2;
|
||||
public const OUTPUT_PLAIN = 4;
|
||||
|
||||
/**
|
||||
* Writes a message to the output.
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
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 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
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function writeln(string|iterable $messages, int $options = 0);
|
||||
|
||||
/**
|
||||
* Sets the verbosity of the output.
|
||||
*
|
||||
* @param self::VERBOSITY_* $level
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setVerbosity(int $level);
|
||||
|
||||
/**
|
||||
* Gets the current verbosity of the output.
|
||||
*
|
||||
* @return self::VERBOSITY_*
|
||||
*/
|
||||
public function getVerbosity(): int;
|
||||
|
||||
/**
|
||||
* Returns whether verbosity is quiet (-q).
|
||||
*/
|
||||
public function isQuiet(): bool;
|
||||
|
||||
/**
|
||||
* Returns whether verbosity is verbose (-v).
|
||||
*/
|
||||
public function isVerbose(): bool;
|
||||
|
||||
/**
|
||||
* Returns whether verbosity is very verbose (-vv).
|
||||
*/
|
||||
public function isVeryVerbose(): bool;
|
||||
|
||||
/**
|
||||
* Returns whether verbosity is debug (-vvv).
|
||||
*/
|
||||
public function isDebug(): bool;
|
||||
|
||||
/**
|
||||
* Sets the decorated flag.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setDecorated(bool $decorated);
|
||||
|
||||
/**
|
||||
* Gets the decorated flag.
|
||||
*/
|
||||
public function isDecorated(): bool;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setFormatter(OutputFormatterInterface $formatter);
|
||||
|
||||
/**
|
||||
* Returns current output formatter instance.
|
||||
*/
|
||||
public function getFormatter(): OutputFormatterInterface;
|
||||
}
|
125
vendor/symfony/console/Output/StreamOutput.php
vendored
Normal file
125
vendor/symfony/console/Output/StreamOutput.php
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* StreamOutput writes the output to a given stream.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* $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));
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class StreamOutput extends Output
|
||||
{
|
||||
/** @var resource */
|
||||
private $stream;
|
||||
|
||||
/**
|
||||
* @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)
|
||||
* @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
|
||||
*
|
||||
* @throws InvalidArgumentException When first argument is not a real stream
|
||||
*/
|
||||
public function __construct($stream, int $verbosity = self::VERBOSITY_NORMAL, ?bool $decorated = null, ?OutputFormatterInterface $formatter = null)
|
||||
{
|
||||
if (!\is_resource($stream) || 'stream' !== get_resource_type($stream)) {
|
||||
throw new InvalidArgumentException('The StreamOutput class needs a stream as its first argument.');
|
||||
}
|
||||
|
||||
$this->stream = $stream;
|
||||
|
||||
$decorated ??= $this->hasColorSupport();
|
||||
|
||||
parent::__construct($verbosity, $decorated, $formatter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the stream attached to this StreamOutput instance.
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public function getStream()
|
||||
{
|
||||
return $this->stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doWrite(string $message, bool $newline)
|
||||
{
|
||||
if ($newline) {
|
||||
$message .= \PHP_EOL;
|
||||
}
|
||||
|
||||
@fwrite($this->stream, $message);
|
||||
|
||||
fflush($this->stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the stream supports colorization.
|
||||
*
|
||||
* Colorization is disabled if not supported by the stream:
|
||||
*
|
||||
* 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(): bool
|
||||
{
|
||||
// Follow https://no-color.org/
|
||||
if (isset($_SERVER['NO_COLOR']) || false !== getenv('NO_COLOR')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
if ('\\' === \DIRECTORY_SEPARATOR && @sapi_windows_vt100_support($this->stream)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ('Hyper' === getenv('TERM_PROGRAM')
|
||||
|| false !== getenv('COLORTERM')
|
||||
|| false !== getenv('ANSICON')
|
||||
|| 'ON' === getenv('ConEmuANSI')
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ('dumb' === $term = (string) getenv('TERM')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
61
vendor/symfony/console/Output/TrimmedBufferOutput.php
vendored
Normal file
61
vendor/symfony/console/Output/TrimmedBufferOutput.php
vendored
Normal 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doWrite(string $message, bool $newline)
|
||||
{
|
||||
$this->buffer .= $message;
|
||||
|
||||
if ($newline) {
|
||||
$this->buffer .= \PHP_EOL;
|
||||
}
|
||||
|
||||
$this->buffer = substr($this->buffer, 0 - $this->maxLength);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user