diff options
Diffstat (limited to 'vendor/symfony/console/Output')
-rw-r--r-- | vendor/symfony/console/Output/AnsiColorMode.php | 106 | ||||
-rw-r--r-- | vendor/symfony/console/Output/BufferedOutput.php | 40 | ||||
-rw-r--r-- | vendor/symfony/console/Output/ConsoleOutput.php | 153 | ||||
-rw-r--r-- | vendor/symfony/console/Output/ConsoleOutputInterface.php | 30 | ||||
-rw-r--r-- | vendor/symfony/console/Output/ConsoleSectionOutput.php | 237 | ||||
-rw-r--r-- | vendor/symfony/console/Output/NullOutput.php | 89 | ||||
-rw-r--r-- | vendor/symfony/console/Output/Output.php | 138 | ||||
-rw-r--r-- | vendor/symfony/console/Output/OutputInterface.php | 100 | ||||
-rw-r--r-- | vendor/symfony/console/Output/StreamOutput.php | 122 | ||||
-rw-r--r-- | vendor/symfony/console/Output/TrimmedBufferOutput.php | 58 |
10 files changed, 1073 insertions, 0 deletions
diff --git a/vendor/symfony/console/Output/AnsiColorMode.php b/vendor/symfony/console/Output/AnsiColorMode.php new file mode 100644 index 0000000..ca40ffb --- /dev/null +++ b/vendor/symfony/console/Output/AnsiColorMode.php | |||
@@ -0,0 +1,106 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\Console\Output; | ||
13 | |||
14 | use Symfony\Component\Console\Exception\InvalidArgumentException; | ||
15 | |||
16 | /** | ||
17 | * @author Fabien Potencier <fabien@symfony.com> | ||
18 | * @author Julien Boudry <julien@condorcet.vote> | ||
19 | */ | ||
20 | enum AnsiColorMode | ||
21 | { | ||
22 | /* | ||
23 | * Classical 4-bit Ansi colors, including 8 classical colors and 8 bright color. Output syntax is "ESC[${foreGroundColorcode};${backGroundColorcode}m" | ||
24 | * Must be compatible with all terminals and it's the minimal version supported. | ||
25 | */ | ||
26 | case Ansi4; | ||
27 | |||
28 | /* | ||
29 | * 8-bit Ansi colors (240 different colors + 16 duplicate color codes, ensuring backward compatibility). | ||
30 | * Output syntax is: "ESC[38;5;${foreGroundColorcode};48;5;${backGroundColorcode}m" | ||
31 | * Should be compatible with most terminals. | ||
32 | */ | ||
33 | case Ansi8; | ||
34 | |||
35 | /* | ||
36 | * 24-bit Ansi colors (RGB). | ||
37 | * Output syntax is: "ESC[38;2;${foreGroundColorcodeRed};${foreGroundColorcodeGreen};${foreGroundColorcodeBlue};48;2;${backGroundColorcodeRed};${backGroundColorcodeGreen};${backGroundColorcodeBlue}m" | ||
38 | * May be compatible with many modern terminals. | ||
39 | */ | ||
40 | case Ansi24; | ||
41 | |||
42 | /** | ||
43 | * Converts an RGB hexadecimal color to the corresponding Ansi code. | ||
44 | */ | ||
45 | public function convertFromHexToAnsiColorCode(string $hexColor): string | ||
46 | { | ||
47 | $hexColor = str_replace('#', '', $hexColor); | ||
48 | |||
49 | if (3 === \strlen($hexColor)) { | ||
50 | $hexColor = $hexColor[0].$hexColor[0].$hexColor[1].$hexColor[1].$hexColor[2].$hexColor[2]; | ||
51 | } | ||
52 | |||
53 | if (6 !== \strlen($hexColor)) { | ||
54 | throw new InvalidArgumentException(sprintf('Invalid "#%s" color.', $hexColor)); | ||
55 | } | ||
56 | |||
57 | $color = hexdec($hexColor); | ||
58 | |||
59 | $r = ($color >> 16) & 255; | ||
60 | $g = ($color >> 8) & 255; | ||
61 | $b = $color & 255; | ||
62 | |||
63 | return match ($this) { | ||
64 | self::Ansi4 => (string) $this->convertFromRGB($r, $g, $b), | ||
65 | self::Ansi8 => '8;5;'.((string) $this->convertFromRGB($r, $g, $b)), | ||
66 | self::Ansi24 => sprintf('8;2;%d;%d;%d', $r, $g, $b), | ||
67 | }; | ||
68 | } | ||
69 | |||
70 | private function convertFromRGB(int $r, int $g, int $b): int | ||
71 | { | ||
72 | return match ($this) { | ||
73 | self::Ansi4 => $this->degradeHexColorToAnsi4($r, $g, $b), | ||
74 | self::Ansi8 => $this->degradeHexColorToAnsi8($r, $g, $b), | ||
75 | default => throw new InvalidArgumentException("RGB cannot be converted to {$this->name}."), | ||
76 | }; | ||
77 | } | ||
78 | |||
79 | private function degradeHexColorToAnsi4(int $r, int $g, int $b): int | ||
80 | { | ||
81 | return round($b / 255) << 2 | (round($g / 255) << 1) | round($r / 255); | ||
82 | } | ||
83 | |||
84 | /** | ||
85 | * Inspired from https://github.com/ajalt/colormath/blob/e464e0da1b014976736cf97250063248fc77b8e7/colormath/src/commonMain/kotlin/com/github/ajalt/colormath/model/Ansi256.kt code (MIT license). | ||
86 | */ | ||
87 | private function degradeHexColorToAnsi8(int $r, int $g, int $b): int | ||
88 | { | ||
89 | if ($r === $g && $g === $b) { | ||
90 | if ($r < 8) { | ||
91 | return 16; | ||
92 | } | ||
93 | |||
94 | if ($r > 248) { | ||
95 | return 231; | ||
96 | } | ||
97 | |||
98 | return (int) round(($r - 8) / 247 * 24) + 232; | ||
99 | } else { | ||
100 | return 16 + | ||
101 | (36 * (int) round($r / 255 * 5)) + | ||
102 | (6 * (int) round($g / 255 * 5)) + | ||
103 | (int) round($b / 255 * 5); | ||
104 | } | ||
105 | } | ||
106 | } | ||
diff --git a/vendor/symfony/console/Output/BufferedOutput.php b/vendor/symfony/console/Output/BufferedOutput.php new file mode 100644 index 0000000..3c8d390 --- /dev/null +++ b/vendor/symfony/console/Output/BufferedOutput.php | |||
@@ -0,0 +1,40 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\Console\Output; | ||
13 | |||
14 | /** | ||
15 | * @author Jean-François Simon <contact@jfsimon.fr> | ||
16 | */ | ||
17 | class BufferedOutput extends Output | ||
18 | { | ||
19 | private string $buffer = ''; | ||
20 | |||
21 | /** | ||
22 | * Empties buffer and returns its content. | ||
23 | */ | ||
24 | public function fetch(): string | ||
25 | { | ||
26 | $content = $this->buffer; | ||
27 | $this->buffer = ''; | ||
28 | |||
29 | return $content; | ||
30 | } | ||
31 | |||
32 | protected function doWrite(string $message, bool $newline): void | ||
33 | { | ||
34 | $this->buffer .= $message; | ||
35 | |||
36 | if ($newline) { | ||
37 | $this->buffer .= \PHP_EOL; | ||
38 | } | ||
39 | } | ||
40 | } | ||
diff --git a/vendor/symfony/console/Output/ConsoleOutput.php b/vendor/symfony/console/Output/ConsoleOutput.php new file mode 100644 index 0000000..2ad3dbc --- /dev/null +++ b/vendor/symfony/console/Output/ConsoleOutput.php | |||
@@ -0,0 +1,153 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\Console\Output; | ||
13 | |||
14 | use Symfony\Component\Console\Formatter\OutputFormatterInterface; | ||
15 | |||
16 | /** | ||
17 | * ConsoleOutput is the default class for all CLI output. It uses STDOUT and STDERR. | ||
18 | * | ||
19 | * This class is a convenient wrapper around `StreamOutput` for both STDOUT and STDERR. | ||
20 | * | ||
21 | * $output = new ConsoleOutput(); | ||
22 | * | ||
23 | * This is equivalent to: | ||
24 | * | ||
25 | * $output = new StreamOutput(fopen('php://stdout', 'w')); | ||
26 | * $stdErr = new StreamOutput(fopen('php://stderr', 'w')); | ||
27 | * | ||
28 | * @author Fabien Potencier <fabien@symfony.com> | ||
29 | */ | ||
30 | class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface | ||
31 | { | ||
32 | private OutputInterface $stderr; | ||
33 | private array $consoleSectionOutputs = []; | ||
34 | |||
35 | /** | ||
36 | * @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface) | ||
37 | * @param bool|null $decorated Whether to decorate messages (null for auto-guessing) | ||
38 | * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter) | ||
39 | */ | ||
40 | public function __construct(int $verbosity = self::VERBOSITY_NORMAL, ?bool $decorated = null, ?OutputFormatterInterface $formatter = null) | ||
41 | { | ||
42 | parent::__construct($this->openOutputStream(), $verbosity, $decorated, $formatter); | ||
43 | |||
44 | if (null === $formatter) { | ||
45 | // for BC reasons, stdErr has it own Formatter only when user don't inject a specific formatter. | ||
46 | $this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated); | ||
47 | |||
48 | return; | ||
49 | } | ||
50 | |||
51 | $actualDecorated = $this->isDecorated(); | ||
52 | $this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated, $this->getFormatter()); | ||
53 | |||
54 | if (null === $decorated) { | ||
55 | $this->setDecorated($actualDecorated && $this->stderr->isDecorated()); | ||
56 | } | ||
57 | } | ||
58 | |||
59 | /** | ||
60 | * Creates a new output section. | ||
61 | */ | ||
62 | public function section(): ConsoleSectionOutput | ||
63 | { | ||
64 | return new ConsoleSectionOutput($this->getStream(), $this->consoleSectionOutputs, $this->getVerbosity(), $this->isDecorated(), $this->getFormatter()); | ||
65 | } | ||
66 | |||
67 | public function setDecorated(bool $decorated): void | ||
68 | { | ||
69 | parent::setDecorated($decorated); | ||
70 | $this->stderr->setDecorated($decorated); | ||
71 | } | ||
72 | |||
73 | public function setFormatter(OutputFormatterInterface $formatter): void | ||
74 | { | ||
75 | parent::setFormatter($formatter); | ||
76 | $this->stderr->setFormatter($formatter); | ||
77 | } | ||
78 | |||
79 | public function setVerbosity(int $level): void | ||
80 | { | ||
81 | parent::setVerbosity($level); | ||
82 | $this->stderr->setVerbosity($level); | ||
83 | } | ||
84 | |||
85 | public function getErrorOutput(): OutputInterface | ||
86 | { | ||
87 | return $this->stderr; | ||
88 | } | ||
89 | |||
90 | public function setErrorOutput(OutputInterface $error): void | ||
91 | { | ||
92 | $this->stderr = $error; | ||
93 | } | ||
94 | |||
95 | /** | ||
96 | * Returns true if current environment supports writing console output to | ||
97 | * STDOUT. | ||
98 | */ | ||
99 | protected function hasStdoutSupport(): bool | ||
100 | { | ||
101 | return false === $this->isRunningOS400(); | ||
102 | } | ||
103 | |||
104 | /** | ||
105 | * Returns true if current environment supports writing console output to | ||
106 | * STDERR. | ||
107 | */ | ||
108 | protected function hasStderrSupport(): bool | ||
109 | { | ||
110 | return false === $this->isRunningOS400(); | ||
111 | } | ||
112 | |||
113 | /** | ||
114 | * Checks if current executing environment is IBM iSeries (OS400), which | ||
115 | * doesn't properly convert character-encodings between ASCII to EBCDIC. | ||
116 | */ | ||
117 | private function isRunningOS400(): bool | ||
118 | { | ||
119 | $checks = [ | ||
120 | \function_exists('php_uname') ? php_uname('s') : '', | ||
121 | getenv('OSTYPE'), | ||
122 | \PHP_OS, | ||
123 | ]; | ||
124 | |||
125 | return false !== stripos(implode(';', $checks), 'OS400'); | ||
126 | } | ||
127 | |||
128 | /** | ||
129 | * @return resource | ||
130 | */ | ||
131 | private function openOutputStream() | ||
132 | { | ||
133 | if (!$this->hasStdoutSupport()) { | ||
134 | return fopen('php://output', 'w'); | ||
135 | } | ||
136 | |||
137 | // Use STDOUT when possible to prevent from opening too many file descriptors | ||
138 | return \defined('STDOUT') ? \STDOUT : (@fopen('php://stdout', 'w') ?: fopen('php://output', 'w')); | ||
139 | } | ||
140 | |||
141 | /** | ||
142 | * @return resource | ||
143 | */ | ||
144 | private function openErrorStream() | ||
145 | { | ||
146 | if (!$this->hasStderrSupport()) { | ||
147 | return fopen('php://output', 'w'); | ||
148 | } | ||
149 | |||
150 | // Use STDERR when possible to prevent from opening too many file descriptors | ||
151 | return \defined('STDERR') ? \STDERR : (@fopen('php://stderr', 'w') ?: fopen('php://output', 'w')); | ||
152 | } | ||
153 | } | ||
diff --git a/vendor/symfony/console/Output/ConsoleOutputInterface.php b/vendor/symfony/console/Output/ConsoleOutputInterface.php new file mode 100644 index 0000000..1f8f147 --- /dev/null +++ b/vendor/symfony/console/Output/ConsoleOutputInterface.php | |||
@@ -0,0 +1,30 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\Console\Output; | ||
13 | |||
14 | /** | ||
15 | * ConsoleOutputInterface is the interface implemented by ConsoleOutput class. | ||
16 | * This adds information about stderr and section output stream. | ||
17 | * | ||
18 | * @author Dariusz Górecki <darek.krk@gmail.com> | ||
19 | */ | ||
20 | interface ConsoleOutputInterface extends OutputInterface | ||
21 | { | ||
22 | /** | ||
23 | * Gets the OutputInterface for errors. | ||
24 | */ | ||
25 | public function getErrorOutput(): OutputInterface; | ||
26 | |||
27 | public function setErrorOutput(OutputInterface $error): void; | ||
28 | |||
29 | public function section(): ConsoleSectionOutput; | ||
30 | } | ||
diff --git a/vendor/symfony/console/Output/ConsoleSectionOutput.php b/vendor/symfony/console/Output/ConsoleSectionOutput.php new file mode 100644 index 0000000..09aa7fe --- /dev/null +++ b/vendor/symfony/console/Output/ConsoleSectionOutput.php | |||
@@ -0,0 +1,237 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\Console\Output; | ||
13 | |||
14 | use Symfony\Component\Console\Formatter\OutputFormatterInterface; | ||
15 | use Symfony\Component\Console\Helper\Helper; | ||
16 | use Symfony\Component\Console\Terminal; | ||
17 | |||
18 | /** | ||
19 | * @author Pierre du Plessis <pdples@gmail.com> | ||
20 | * @author Gabriel Ostrolucký <gabriel.ostrolucky@gmail.com> | ||
21 | */ | ||
22 | class ConsoleSectionOutput extends StreamOutput | ||
23 | { | ||
24 | private array $content = []; | ||
25 | private int $lines = 0; | ||
26 | private array $sections; | ||
27 | private Terminal $terminal; | ||
28 | private int $maxHeight = 0; | ||
29 | |||
30 | /** | ||
31 | * @param resource $stream | ||
32 | * @param ConsoleSectionOutput[] $sections | ||
33 | */ | ||
34 | public function __construct($stream, array &$sections, int $verbosity, bool $decorated, OutputFormatterInterface $formatter) | ||
35 | { | ||
36 | parent::__construct($stream, $verbosity, $decorated, $formatter); | ||
37 | array_unshift($sections, $this); | ||
38 | $this->sections = &$sections; | ||
39 | $this->terminal = new Terminal(); | ||
40 | } | ||
41 | |||
42 | /** | ||
43 | * Defines a maximum number of lines for this section. | ||
44 | * | ||
45 | * When more lines are added, the section will automatically scroll to the | ||
46 | * end (i.e. remove the first lines to comply with the max height). | ||
47 | */ | ||
48 | public function setMaxHeight(int $maxHeight): void | ||
49 | { | ||
50 | // when changing max height, clear output of current section and redraw again with the new height | ||
51 | $previousMaxHeight = $this->maxHeight; | ||
52 | $this->maxHeight = $maxHeight; | ||
53 | $existingContent = $this->popStreamContentUntilCurrentSection($previousMaxHeight ? min($previousMaxHeight, $this->lines) : $this->lines); | ||
54 | |||
55 | parent::doWrite($this->getVisibleContent(), false); | ||
56 | parent::doWrite($existingContent, false); | ||
57 | } | ||
58 | |||
59 | /** | ||
60 | * Clears previous output for this section. | ||
61 | * | ||
62 | * @param int $lines Number of lines to clear. If null, then the entire output of this section is cleared | ||
63 | */ | ||
64 | public function clear(?int $lines = null): void | ||
65 | { | ||
66 | if (!$this->content || !$this->isDecorated()) { | ||
67 | return; | ||
68 | } | ||
69 | |||
70 | if ($lines) { | ||
71 | array_splice($this->content, -$lines); | ||
72 | } else { | ||
73 | $lines = $this->lines; | ||
74 | $this->content = []; | ||
75 | } | ||
76 | |||
77 | $this->lines -= $lines; | ||
78 | |||
79 | parent::doWrite($this->popStreamContentUntilCurrentSection($this->maxHeight ? min($this->maxHeight, $lines) : $lines), false); | ||
80 | } | ||
81 | |||
82 | /** | ||
83 | * Overwrites the previous output with a new message. | ||
84 | */ | ||
85 | public function overwrite(string|iterable $message): void | ||
86 | { | ||
87 | $this->clear(); | ||
88 | $this->writeln($message); | ||
89 | } | ||
90 | |||
91 | public function getContent(): string | ||
92 | { | ||
93 | return implode('', $this->content); | ||
94 | } | ||
95 | |||
96 | public function getVisibleContent(): string | ||
97 | { | ||
98 | if (0 === $this->maxHeight) { | ||
99 | return $this->getContent(); | ||
100 | } | ||
101 | |||
102 | return implode('', \array_slice($this->content, -$this->maxHeight)); | ||
103 | } | ||
104 | |||
105 | /** | ||
106 | * @internal | ||
107 | */ | ||
108 | public function addContent(string $input, bool $newline = true): int | ||
109 | { | ||
110 | $width = $this->terminal->getWidth(); | ||
111 | $lines = explode(\PHP_EOL, $input); | ||
112 | $linesAdded = 0; | ||
113 | $count = \count($lines) - 1; | ||
114 | foreach ($lines as $i => $lineContent) { | ||
115 | // re-add the line break (that has been removed in the above `explode()` for | ||
116 | // - every line that is not the last line | ||
117 | // - if $newline is required, also add it to the last line | ||
118 | if ($i < $count || $newline) { | ||
119 | $lineContent .= \PHP_EOL; | ||
120 | } | ||
121 | |||
122 | // skip line if there is no text (or newline for that matter) | ||
123 | if ('' === $lineContent) { | ||
124 | continue; | ||
125 | } | ||
126 | |||
127 | // For the first line, check if the previous line (last entry of `$this->content`) | ||
128 | // needs to be continued (i.e. does not end with a line break). | ||
129 | if (0 === $i | ||
130 | && (false !== $lastLine = end($this->content)) | ||
131 | && !str_ends_with($lastLine, \PHP_EOL) | ||
132 | ) { | ||
133 | // deduct the line count of the previous line | ||
134 | $this->lines -= (int) ceil($this->getDisplayLength($lastLine) / $width) ?: 1; | ||
135 | // concatenate previous and new line | ||
136 | $lineContent = $lastLine.$lineContent; | ||
137 | // replace last entry of `$this->content` with the new expanded line | ||
138 | array_splice($this->content, -1, 1, $lineContent); | ||
139 | } else { | ||
140 | // otherwise just add the new content | ||
141 | $this->content[] = $lineContent; | ||
142 | } | ||
143 | |||
144 | $linesAdded += (int) ceil($this->getDisplayLength($lineContent) / $width) ?: 1; | ||
145 | } | ||
146 | |||
147 | $this->lines += $linesAdded; | ||
148 | |||
149 | return $linesAdded; | ||
150 | } | ||
151 | |||
152 | /** | ||
153 | * @internal | ||
154 | */ | ||
155 | public function addNewLineOfInputSubmit(): void | ||
156 | { | ||
157 | $this->content[] = \PHP_EOL; | ||
158 | ++$this->lines; | ||
159 | } | ||
160 | |||
161 | protected function doWrite(string $message, bool $newline): void | ||
162 | { | ||
163 | // Simulate newline behavior for consistent output formatting, avoiding extra logic | ||
164 | if (!$newline && str_ends_with($message, \PHP_EOL)) { | ||
165 | $message = substr($message, 0, -\strlen(\PHP_EOL)); | ||
166 | $newline = true; | ||
167 | } | ||
168 | |||
169 | if (!$this->isDecorated()) { | ||
170 | parent::doWrite($message, $newline); | ||
171 | |||
172 | return; | ||
173 | } | ||
174 | |||
175 | // Check if the previous line (last entry of `$this->content`) needs to be continued | ||
176 | // (i.e. does not end with a line break). In which case, it needs to be erased first. | ||
177 | $linesToClear = $deleteLastLine = ($lastLine = end($this->content) ?: '') && !str_ends_with($lastLine, \PHP_EOL) ? 1 : 0; | ||
178 | |||
179 | $linesAdded = $this->addContent($message, $newline); | ||
180 | |||
181 | if ($lineOverflow = $this->maxHeight > 0 && $this->lines > $this->maxHeight) { | ||
182 | // on overflow, clear the whole section and redraw again (to remove the first lines) | ||
183 | $linesToClear = $this->maxHeight; | ||
184 | } | ||
185 | |||
186 | $erasedContent = $this->popStreamContentUntilCurrentSection($linesToClear); | ||
187 | |||
188 | if ($lineOverflow) { | ||
189 | // redraw existing lines of the section | ||
190 | $previousLinesOfSection = \array_slice($this->content, $this->lines - $this->maxHeight, $this->maxHeight - $linesAdded); | ||
191 | parent::doWrite(implode('', $previousLinesOfSection), false); | ||
192 | } | ||
193 | |||
194 | // if the last line was removed, re-print its content together with the new content. | ||
195 | // otherwise, just print the new content. | ||
196 | parent::doWrite($deleteLastLine ? $lastLine.$message : $message, true); | ||
197 | parent::doWrite($erasedContent, false); | ||
198 | } | ||
199 | |||
200 | /** | ||
201 | * At initial stage, cursor is at the end of stream output. This method makes cursor crawl upwards until it hits | ||
202 | * current section. Then it erases content it crawled through. Optionally, it erases part of current section too. | ||
203 | */ | ||
204 | private function popStreamContentUntilCurrentSection(int $numberOfLinesToClearFromCurrentSection = 0): string | ||
205 | { | ||
206 | $numberOfLinesToClear = $numberOfLinesToClearFromCurrentSection; | ||
207 | $erasedContent = []; | ||
208 | |||
209 | foreach ($this->sections as $section) { | ||
210 | if ($section === $this) { | ||
211 | break; | ||
212 | } | ||
213 | |||
214 | $numberOfLinesToClear += $section->maxHeight ? min($section->lines, $section->maxHeight) : $section->lines; | ||
215 | if ('' !== $sectionContent = $section->getVisibleContent()) { | ||
216 | if (!str_ends_with($sectionContent, \PHP_EOL)) { | ||
217 | $sectionContent .= \PHP_EOL; | ||
218 | } | ||
219 | $erasedContent[] = $sectionContent; | ||
220 | } | ||
221 | } | ||
222 | |||
223 | if ($numberOfLinesToClear > 0) { | ||
224 | // move cursor up n lines | ||
225 | parent::doWrite(sprintf("\x1b[%dA", $numberOfLinesToClear), false); | ||
226 | // erase to end of screen | ||
227 | parent::doWrite("\x1b[0J", false); | ||
228 | } | ||
229 | |||
230 | return implode('', array_reverse($erasedContent)); | ||
231 | } | ||
232 | |||
233 | private function getDisplayLength(string $text): int | ||
234 | { | ||
235 | return Helper::width(Helper::removeDecoration($this->getFormatter(), str_replace("\t", ' ', $text))); | ||
236 | } | ||
237 | } | ||
diff --git a/vendor/symfony/console/Output/NullOutput.php b/vendor/symfony/console/Output/NullOutput.php new file mode 100644 index 0000000..40ae332 --- /dev/null +++ b/vendor/symfony/console/Output/NullOutput.php | |||
@@ -0,0 +1,89 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\Console\Output; | ||
13 | |||
14 | use Symfony\Component\Console\Formatter\NullOutputFormatter; | ||
15 | use Symfony\Component\Console\Formatter\OutputFormatterInterface; | ||
16 | |||
17 | /** | ||
18 | * NullOutput suppresses all output. | ||
19 | * | ||
20 | * $output = new NullOutput(); | ||
21 | * | ||
22 | * @author Fabien Potencier <fabien@symfony.com> | ||
23 | * @author Tobias Schultze <http://tobion.de> | ||
24 | */ | ||
25 | class NullOutput implements OutputInterface | ||
26 | { | ||
27 | private NullOutputFormatter $formatter; | ||
28 | |||
29 | public function setFormatter(OutputFormatterInterface $formatter): void | ||
30 | { | ||
31 | // do nothing | ||
32 | } | ||
33 | |||
34 | public function getFormatter(): OutputFormatterInterface | ||
35 | { | ||
36 | // to comply with the interface we must return a OutputFormatterInterface | ||
37 | return $this->formatter ??= new NullOutputFormatter(); | ||
38 | } | ||
39 | |||
40 | public function setDecorated(bool $decorated): void | ||
41 | { | ||
42 | // do nothing | ||
43 | } | ||
44 | |||
45 | public function isDecorated(): bool | ||
46 | { | ||
47 | return false; | ||
48 | } | ||
49 | |||
50 | public function setVerbosity(int $level): void | ||
51 | { | ||
52 | // do nothing | ||
53 | } | ||
54 | |||
55 | public function getVerbosity(): int | ||
56 | { | ||
57 | return self::VERBOSITY_QUIET; | ||
58 | } | ||
59 | |||
60 | public function isQuiet(): bool | ||
61 | { | ||
62 | return true; | ||
63 | } | ||
64 | |||
65 | public function isVerbose(): bool | ||
66 | { | ||
67 | return false; | ||
68 | } | ||
69 | |||
70 | public function isVeryVerbose(): bool | ||
71 | { | ||
72 | return false; | ||
73 | } | ||
74 | |||
75 | public function isDebug(): bool | ||
76 | { | ||
77 | return false; | ||
78 | } | ||
79 | |||
80 | public function writeln(string|iterable $messages, int $options = self::OUTPUT_NORMAL): void | ||
81 | { | ||
82 | // do nothing | ||
83 | } | ||
84 | |||
85 | public function write(string|iterable $messages, bool $newline = false, int $options = self::OUTPUT_NORMAL): void | ||
86 | { | ||
87 | // do nothing | ||
88 | } | ||
89 | } | ||
diff --git a/vendor/symfony/console/Output/Output.php b/vendor/symfony/console/Output/Output.php new file mode 100644 index 0000000..2bb1057 --- /dev/null +++ b/vendor/symfony/console/Output/Output.php | |||
@@ -0,0 +1,138 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\Console\Output; | ||
13 | |||
14 | use Symfony\Component\Console\Formatter\OutputFormatter; | ||
15 | use Symfony\Component\Console\Formatter\OutputFormatterInterface; | ||
16 | |||
17 | /** | ||
18 | * Base class for output classes. | ||
19 | * | ||
20 | * There are five levels of verbosity: | ||
21 | * | ||
22 | * * normal: no option passed (normal output) | ||
23 | * * verbose: -v (more output) | ||
24 | * * very verbose: -vv (highly extended output) | ||
25 | * * debug: -vvv (all debug output) | ||
26 | * * quiet: -q (no output) | ||
27 | * | ||
28 | * @author Fabien Potencier <fabien@symfony.com> | ||
29 | */ | ||
30 | abstract class Output implements OutputInterface | ||
31 | { | ||
32 | private int $verbosity; | ||
33 | private OutputFormatterInterface $formatter; | ||
34 | |||
35 | /** | ||
36 | * @param int|null $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface) | ||
37 | * @param bool $decorated Whether to decorate messages | ||
38 | * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter) | ||
39 | */ | ||
40 | public function __construct(?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = false, ?OutputFormatterInterface $formatter = null) | ||
41 | { | ||
42 | $this->verbosity = $verbosity ?? self::VERBOSITY_NORMAL; | ||
43 | $this->formatter = $formatter ?? new OutputFormatter(); | ||
44 | $this->formatter->setDecorated($decorated); | ||
45 | } | ||
46 | |||
47 | public function setFormatter(OutputFormatterInterface $formatter): void | ||
48 | { | ||
49 | $this->formatter = $formatter; | ||
50 | } | ||
51 | |||
52 | public function getFormatter(): OutputFormatterInterface | ||
53 | { | ||
54 | return $this->formatter; | ||
55 | } | ||
56 | |||
57 | public function setDecorated(bool $decorated): void | ||
58 | { | ||
59 | $this->formatter->setDecorated($decorated); | ||
60 | } | ||
61 | |||
62 | public function isDecorated(): bool | ||
63 | { | ||
64 | return $this->formatter->isDecorated(); | ||
65 | } | ||
66 | |||
67 | public function setVerbosity(int $level): void | ||
68 | { | ||
69 | $this->verbosity = $level; | ||
70 | } | ||
71 | |||
72 | public function getVerbosity(): int | ||
73 | { | ||
74 | return $this->verbosity; | ||
75 | } | ||
76 | |||
77 | public function isQuiet(): bool | ||
78 | { | ||
79 | return self::VERBOSITY_QUIET === $this->verbosity; | ||
80 | } | ||
81 | |||
82 | public function isVerbose(): bool | ||
83 | { | ||
84 | return self::VERBOSITY_VERBOSE <= $this->verbosity; | ||
85 | } | ||
86 | |||
87 | public function isVeryVerbose(): bool | ||
88 | { | ||
89 | return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity; | ||
90 | } | ||
91 | |||
92 | public function isDebug(): bool | ||
93 | { | ||
94 | return self::VERBOSITY_DEBUG <= $this->verbosity; | ||
95 | } | ||
96 | |||
97 | public function writeln(string|iterable $messages, int $options = self::OUTPUT_NORMAL): void | ||
98 | { | ||
99 | $this->write($messages, true, $options); | ||
100 | } | ||
101 | |||
102 | public function write(string|iterable $messages, bool $newline = false, int $options = self::OUTPUT_NORMAL): void | ||
103 | { | ||
104 | if (!is_iterable($messages)) { | ||
105 | $messages = [$messages]; | ||
106 | } | ||
107 | |||
108 | $types = self::OUTPUT_NORMAL | self::OUTPUT_RAW | self::OUTPUT_PLAIN; | ||
109 | $type = $types & $options ?: self::OUTPUT_NORMAL; | ||
110 | |||
111 | $verbosities = self::VERBOSITY_QUIET | self::VERBOSITY_NORMAL | self::VERBOSITY_VERBOSE | self::VERBOSITY_VERY_VERBOSE | self::VERBOSITY_DEBUG; | ||
112 | $verbosity = $verbosities & $options ?: self::VERBOSITY_NORMAL; | ||
113 | |||
114 | if ($verbosity > $this->getVerbosity()) { | ||
115 | return; | ||
116 | } | ||
117 | |||
118 | foreach ($messages as $message) { | ||
119 | switch ($type) { | ||
120 | case OutputInterface::OUTPUT_NORMAL: | ||
121 | $message = $this->formatter->format($message); | ||
122 | break; | ||
123 | case OutputInterface::OUTPUT_RAW: | ||
124 | break; | ||
125 | case OutputInterface::OUTPUT_PLAIN: | ||
126 | $message = strip_tags($this->formatter->format($message)); | ||
127 | break; | ||
128 | } | ||
129 | |||
130 | $this->doWrite($message ?? '', $newline); | ||
131 | } | ||
132 | } | ||
133 | |||
134 | /** | ||
135 | * Writes a message to the output. | ||
136 | */ | ||
137 | abstract protected function doWrite(string $message, bool $newline): void; | ||
138 | } | ||
diff --git a/vendor/symfony/console/Output/OutputInterface.php b/vendor/symfony/console/Output/OutputInterface.php new file mode 100644 index 0000000..41315fb --- /dev/null +++ b/vendor/symfony/console/Output/OutputInterface.php | |||
@@ -0,0 +1,100 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\Console\Output; | ||
13 | |||
14 | use Symfony\Component\Console\Formatter\OutputFormatterInterface; | ||
15 | |||
16 | /** | ||
17 | * OutputInterface is the interface implemented by all Output classes. | ||
18 | * | ||
19 | * @author Fabien Potencier <fabien@symfony.com> | ||
20 | */ | ||
21 | interface OutputInterface | ||
22 | { | ||
23 | public const VERBOSITY_QUIET = 16; | ||
24 | public const VERBOSITY_NORMAL = 32; | ||
25 | public const VERBOSITY_VERBOSE = 64; | ||
26 | public const VERBOSITY_VERY_VERBOSE = 128; | ||
27 | public const VERBOSITY_DEBUG = 256; | ||
28 | |||
29 | public const OUTPUT_NORMAL = 1; | ||
30 | public const OUTPUT_RAW = 2; | ||
31 | public const OUTPUT_PLAIN = 4; | ||
32 | |||
33 | /** | ||
34 | * Writes a message to the output. | ||
35 | * | ||
36 | * @param bool $newline Whether to add a newline | ||
37 | * @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), | ||
38 | * 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL | ||
39 | */ | ||
40 | public function write(string|iterable $messages, bool $newline = false, int $options = 0): void; | ||
41 | |||
42 | /** | ||
43 | * Writes a message to the output and adds a newline at the end. | ||
44 | * | ||
45 | * @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), | ||
46 | * 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL | ||
47 | */ | ||
48 | public function writeln(string|iterable $messages, int $options = 0): void; | ||
49 | |||
50 | /** | ||
51 | * Sets the verbosity of the output. | ||
52 | * | ||
53 | * @param self::VERBOSITY_* $level | ||
54 | */ | ||
55 | public function setVerbosity(int $level): void; | ||
56 | |||
57 | /** | ||
58 | * Gets the current verbosity of the output. | ||
59 | * | ||
60 | * @return self::VERBOSITY_* | ||
61 | */ | ||
62 | public function getVerbosity(): int; | ||
63 | |||
64 | /** | ||
65 | * Returns whether verbosity is quiet (-q). | ||
66 | */ | ||
67 | public function isQuiet(): bool; | ||
68 | |||
69 | /** | ||
70 | * Returns whether verbosity is verbose (-v). | ||
71 | */ | ||
72 | public function isVerbose(): bool; | ||
73 | |||
74 | /** | ||
75 | * Returns whether verbosity is very verbose (-vv). | ||
76 | */ | ||
77 | public function isVeryVerbose(): bool; | ||
78 | |||
79 | /** | ||
80 | * Returns whether verbosity is debug (-vvv). | ||
81 | */ | ||
82 | public function isDebug(): bool; | ||
83 | |||
84 | /** | ||
85 | * Sets the decorated flag. | ||
86 | */ | ||
87 | public function setDecorated(bool $decorated): void; | ||
88 | |||
89 | /** | ||
90 | * Gets the decorated flag. | ||
91 | */ | ||
92 | public function isDecorated(): bool; | ||
93 | |||
94 | public function setFormatter(OutputFormatterInterface $formatter): void; | ||
95 | |||
96 | /** | ||
97 | * Returns current output formatter instance. | ||
98 | */ | ||
99 | public function getFormatter(): OutputFormatterInterface; | ||
100 | } | ||
diff --git a/vendor/symfony/console/Output/StreamOutput.php b/vendor/symfony/console/Output/StreamOutput.php new file mode 100644 index 0000000..b46f4d2 --- /dev/null +++ b/vendor/symfony/console/Output/StreamOutput.php | |||
@@ -0,0 +1,122 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\Console\Output; | ||
13 | |||
14 | use Symfony\Component\Console\Exception\InvalidArgumentException; | ||
15 | use Symfony\Component\Console\Formatter\OutputFormatterInterface; | ||
16 | |||
17 | /** | ||
18 | * StreamOutput writes the output to a given stream. | ||
19 | * | ||
20 | * Usage: | ||
21 | * | ||
22 | * $output = new StreamOutput(fopen('php://stdout', 'w')); | ||
23 | * | ||
24 | * As `StreamOutput` can use any stream, you can also use a file: | ||
25 | * | ||
26 | * $output = new StreamOutput(fopen('/path/to/output.log', 'a', false)); | ||
27 | * | ||
28 | * @author Fabien Potencier <fabien@symfony.com> | ||
29 | */ | ||
30 | class StreamOutput extends Output | ||
31 | { | ||
32 | /** @var resource */ | ||
33 | private $stream; | ||
34 | |||
35 | /** | ||
36 | * @param resource $stream A stream resource | ||
37 | * @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface) | ||
38 | * @param bool|null $decorated Whether to decorate messages (null for auto-guessing) | ||
39 | * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter) | ||
40 | * | ||
41 | * @throws InvalidArgumentException When first argument is not a real stream | ||
42 | */ | ||
43 | public function __construct($stream, int $verbosity = self::VERBOSITY_NORMAL, ?bool $decorated = null, ?OutputFormatterInterface $formatter = null) | ||
44 | { | ||
45 | if (!\is_resource($stream) || 'stream' !== get_resource_type($stream)) { | ||
46 | throw new InvalidArgumentException('The StreamOutput class needs a stream as its first argument.'); | ||
47 | } | ||
48 | |||
49 | $this->stream = $stream; | ||
50 | |||
51 | $decorated ??= $this->hasColorSupport(); | ||
52 | |||
53 | parent::__construct($verbosity, $decorated, $formatter); | ||
54 | } | ||
55 | |||
56 | /** | ||
57 | * Gets the stream attached to this StreamOutput instance. | ||
58 | * | ||
59 | * @return resource | ||
60 | */ | ||
61 | public function getStream() | ||
62 | { | ||
63 | return $this->stream; | ||
64 | } | ||
65 | |||
66 | protected function doWrite(string $message, bool $newline): void | ||
67 | { | ||
68 | if ($newline) { | ||
69 | $message .= \PHP_EOL; | ||
70 | } | ||
71 | |||
72 | @fwrite($this->stream, $message); | ||
73 | |||
74 | fflush($this->stream); | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * Returns true if the stream supports colorization. | ||
79 | * | ||
80 | * Colorization is disabled if not supported by the stream: | ||
81 | * | ||
82 | * This is tricky on Windows, because Cygwin, Msys2 etc emulate pseudo | ||
83 | * terminals via named pipes, so we can only check the environment. | ||
84 | * | ||
85 | * Reference: Composer\XdebugHandler\Process::supportsColor | ||
86 | * https://github.com/composer/xdebug-handler | ||
87 | * | ||
88 | * @return bool true if the stream supports colorization, false otherwise | ||
89 | */ | ||
90 | protected function hasColorSupport(): bool | ||
91 | { | ||
92 | // Follow https://no-color.org/ | ||
93 | if ('' !== ($_SERVER['NO_COLOR'] ?? getenv('NO_COLOR') ?: '')) { | ||
94 | return false; | ||
95 | } | ||
96 | |||
97 | // Detect msysgit/mingw and assume this is a tty because detection | ||
98 | // does not work correctly, see https://github.com/composer/composer/issues/9690 | ||
99 | if (!@stream_isatty($this->stream) && !\in_array(strtoupper((string) getenv('MSYSTEM')), ['MINGW32', 'MINGW64'], true)) { | ||
100 | return false; | ||
101 | } | ||
102 | |||
103 | if ('\\' === \DIRECTORY_SEPARATOR && @sapi_windows_vt100_support($this->stream)) { | ||
104 | return true; | ||
105 | } | ||
106 | |||
107 | if ('Hyper' === getenv('TERM_PROGRAM') | ||
108 | || false !== getenv('COLORTERM') | ||
109 | || false !== getenv('ANSICON') | ||
110 | || 'ON' === getenv('ConEmuANSI') | ||
111 | ) { | ||
112 | return true; | ||
113 | } | ||
114 | |||
115 | if ('dumb' === $term = (string) getenv('TERM')) { | ||
116 | return false; | ||
117 | } | ||
118 | |||
119 | // See https://github.com/chalk/supports-color/blob/d4f413efaf8da045c5ab440ed418ef02dbb28bf1/index.js#L157 | ||
120 | return preg_match('/^((screen|xterm|vt100|vt220|putty|rxvt|ansi|cygwin|linux).*)|(.*-256(color)?(-bce)?)$/', $term); | ||
121 | } | ||
122 | } | ||
diff --git a/vendor/symfony/console/Output/TrimmedBufferOutput.php b/vendor/symfony/console/Output/TrimmedBufferOutput.php new file mode 100644 index 0000000..c1862a2 --- /dev/null +++ b/vendor/symfony/console/Output/TrimmedBufferOutput.php | |||
@@ -0,0 +1,58 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | namespace Symfony\Component\Console\Output; | ||
13 | |||
14 | use Symfony\Component\Console\Exception\InvalidArgumentException; | ||
15 | use Symfony\Component\Console\Formatter\OutputFormatterInterface; | ||
16 | |||
17 | /** | ||
18 | * A BufferedOutput that keeps only the last N chars. | ||
19 | * | ||
20 | * @author Jérémy Derussé <jeremy@derusse.com> | ||
21 | */ | ||
22 | class TrimmedBufferOutput extends Output | ||
23 | { | ||
24 | private int $maxLength; | ||
25 | private string $buffer = ''; | ||
26 | |||
27 | public function __construct(int $maxLength, ?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = false, ?OutputFormatterInterface $formatter = null) | ||
28 | { | ||
29 | if ($maxLength <= 0) { | ||
30 | throw new InvalidArgumentException(sprintf('"%s()" expects a strictly positive maxLength. Got %d.', __METHOD__, $maxLength)); | ||
31 | } | ||
32 | |||
33 | parent::__construct($verbosity, $decorated, $formatter); | ||
34 | $this->maxLength = $maxLength; | ||
35 | } | ||
36 | |||
37 | /** | ||
38 | * Empties buffer and returns its content. | ||
39 | */ | ||
40 | public function fetch(): string | ||
41 | { | ||
42 | $content = $this->buffer; | ||
43 | $this->buffer = ''; | ||
44 | |||
45 | return $content; | ||
46 | } | ||
47 | |||
48 | protected function doWrite(string $message, bool $newline): void | ||
49 | { | ||
50 | $this->buffer .= $message; | ||
51 | |||
52 | if ($newline) { | ||
53 | $this->buffer .= \PHP_EOL; | ||
54 | } | ||
55 | |||
56 | $this->buffer = substr($this->buffer, 0 - $this->maxLength); | ||
57 | } | ||
58 | } | ||