Skip to content

Commit

Permalink
Merge branch '4.4' into 5.1
Browse files Browse the repository at this point in the history
* 4.4:
  [PhpUnitBridge] Fix qualification of deprecations triggered by the debug class loader
  Improve return phpdoc for Normalizer
  Use a partial buffer in SymfonyStyle
  Fix console closing tag
  Fix typo in comment
  [VarDumper] fix casting resources turned into objects on PHP 8
  • Loading branch information
derrabus committed Nov 26, 2020
2 parents ae80d52 + 061d2c7 commit ccacf6b
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 5 deletions.
8 changes: 8 additions & 0 deletions Formatter/OutputFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ class OutputFormatter implements WrappableOutputFormatterInterface
private $styles = [];
private $styleStack;

public function __clone()
{
$this->styleStack = clone $this->styleStack;
foreach ($this->styles as $key => $value) {
$this->styles[$key] = clone $value;
}
}

/**
* Escapes "<" special char in given text.
*
Expand Down
67 changes: 67 additions & 0 deletions Output/TrimmedBufferOutput.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* 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é <[email protected]>
*/
class TrimmedBufferOutput extends Output
{
private $maxLength;
private $buffer = '';

public function __construct(
?int $verbosity = self::VERBOSITY_NORMAL,
bool $decorated = false,
OutputFormatterInterface $formatter = null,
int $maxLength
) {
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.
*
* @return string
*/
public function fetch()
{
$content = $this->buffer;
$this->buffer = '';

return $content;
}

/**
* {@inheritdoc}
*/
protected function doWrite($message, $newline)
{
$this->buffer .= $message;

if ($newline) {
$this->buffer .= \PHP_EOL;
}

$this->buffer = substr($this->buffer, 0 - $this->maxLength);
}
}
9 changes: 4 additions & 5 deletions Style/SymfonyStyle.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
use Symfony\Component\Console\Helper\TableCell;
use Symfony\Component\Console\Helper\TableSeparator;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\TrimmedBufferOutput;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Question\Question;
Expand All @@ -46,7 +46,7 @@ class SymfonyStyle extends OutputStyle
public function __construct(InputInterface $input, OutputInterface $output)
{
$this->input = $input;
$this->bufferedOutput = new BufferedOutput($output->getVerbosity(), false, clone $output->getFormatter());
$this->bufferedOutput = new TrimmedBufferOutput($output->getVerbosity(), false, clone $output->getFormatter(), \DIRECTORY_SEPARATOR === '\\' ? 4 : 2);
// Windows cmd wraps lines as soon as the terminal width is reached, whether there are following chars or not.
$width = (new Terminal())->getWidth() ?: self::MAX_LINE_LENGTH;
$this->lineLength = min($width - (int) (\DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH);
Expand Down Expand Up @@ -444,9 +444,8 @@ private function autoPrependText(): void

private function writeBuffer(string $message, bool $newLine, int $type): void
{
// We need to know if the two last chars are PHP_EOL
// Preserve the last 4 chars inserted (PHP_EOL on windows is two chars) in the history buffer
$this->bufferedOutput->write(substr($message, -4), $newLine, $type);
// We need to know if the last chars are PHP_EOL
$this->bufferedOutput->write($message, $newLine, $type);
}

private function createBlock(iterable $messages, string $type = null, string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = false): array
Expand Down
13 changes: 13 additions & 0 deletions Tests/Fixtures/Style/SymfonyStyle/command/command_20.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

// Ensure that closing tag is applied once
return function (InputInterface $input, OutputInterface $output) {
$output->setDecorated(true);
$output = new SymfonyStyle($input, $output);
$output->write('<question>do you want <comment>something</>');
$output->writeln('?</>');
};
1 change: 1 addition & 0 deletions Tests/Fixtures/Style/SymfonyStyle/output/output_20.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
do you want something?
15 changes: 15 additions & 0 deletions Tests/Style/SymfonyStyleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Console\Tester\CommandTester;
Expand Down Expand Up @@ -115,4 +117,17 @@ public function testGetErrorStyleUsesTheCurrentOutputIfNoErrorOutputIsAvailable(

$this->assertInstanceOf(SymfonyStyle::class, $style->getErrorStyle());
}

public function testMemoryConsumption()
{
$io = new SymfonyStyle(new ArrayInput([]), new NullOutput());
$str = 'teststr';
$io->writeln($str, SymfonyStyle::VERBOSITY_QUIET);
$start = memory_get_usage();
for ($i = 0; $i < 100; ++$i) {
$io->writeln($str, SymfonyStyle::VERBOSITY_QUIET);
}

$this->assertSame(0, memory_get_usage() - $start);
}
}

0 comments on commit ccacf6b

Please sign in to comment.