8000 [Console] SymfonyStyle : fix & automate block gaps. by ogizanagi · Pull Request #14623 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Console] SymfonyStyle : fix & automate block gaps. #14623

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 8, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 90 additions & 10 deletions src/Symfony/Component/Console/Style/SymfonyStyle.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Symfony\Component\Console\Helper\SymfonyQuestionHelper;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\ConfirmationQuestion;
Expand All @@ -36,6 +37,7 @@ class SymfonyStyle extends OutputStyle
private $questionHelper;
private $progressBar;
private $lineLength;
private $bufferedOutput;

/**
* @param InputInterface $input
Expand All @@ -45,6 +47,7 @@ public function __construct(InputInterface $input, OutputInterface $output)
{
$this->input = $input;
$this->lineLength = min($this->getTerminalWidth(), self::MAX_LINE_LENGTH);
$this->bufferedOutput = new BufferedOutput($output->getVerbosity(), false, clone $output->getFormatter());

parent::__construct($output);
}
Expand All @@ -60,6 +63,7 @@ public function __construct(InputInterface $input, OutputInterface $output)
*/
public function block($messages, $type = null, $style = null, $prefix = ' ', $padding = false)
{
$this->autoPrependBlock();
$messages = is_array($messages) ? array_values($messages) : array($messages);
$lines = array();

Expand All @@ -71,7 +75,7 @@ public function block($messages, $type = null, $style = null, $prefix = ' ', $pa
// wrap and add newlines for each element
foreach ($messages as $key => $message) {
$message = OutputFormatter::escape($message);
$lines = array_merge($lines, explode("\n", wordwrap($message, $this->lineLength - Helper::strlen($prefix))));
$lines = array_merge($lines, explode(PHP_EOL, wordwrap($message, $this->lineLength - Helper::strlen($prefix), PHP_EOL)));

if (count($messages) > 1 && $key < count($messages) - 1) {
$lines[] = '';
Expand All @@ -92,44 +96,57 @@ public function block($messages, $type = null, $style = null, $prefix = ' ', $pa
}
}

$this->writeln(implode("\n", $lines)."\n");
$this->writeln($lines);
$this->newLine();
}

/**
* {@inheritdoc}
*/
public function title($message)
{
$this->writeln(sprintf("\n<comment>%s</>\n<comment>%s</>\n", $message, str_repeat('=', strlen($message))));
$this->autoPrependBlock();
$this->writeln(array(
sprintf('<comment>%s</>', $message),
sprintf('<comment>%s</>', str_repeat('=', strlen($message))),
));
$this->newLine();
}

/**
* {@inheritdoc}
*/
public function section($message)
{
$this->writeln(sprintf("<comment>%s</>\n<comment>%s</>\n", $message, str_repeat('-', strlen($message))));
$this->autoPrependBlock();
$this->writeln(array(
sprintf('<comment>%s</>', $message),
sprintf('<comment>%s</>', str_repeat('-', strlen($message))),
));
$this->newLine();
}

/**
* {@inheritdoc}
*/
public function listing(array $elements)
{
$this->autoPrependText();
$elements = array_map(function ($element) {
return sprintf(' * %s', $element);
},
$elements
);
return sprintf(' * %s', $element);
}, $elements);

$this->writeln(implode("\n", $elements)."\n");
$this->writeln($elements);
$this->newLine();
}

/**
* {@inheritdoc}
*/
public function text($message)
{
$this->autoPrependText();

if (!is_array($message)) {
$this->writeln(sprintf(' // %s', $message));

Expand Down Expand Up @@ -290,17 +307,51 @@ public function createProgressBar($max = 0)
*/
public function askQuestion(Question $question)
{
if ($this->input->isInteractive()) {
$this->autoPrependBlock();
}

if (!$this->questionHelper) {
$this->questionHelper = new SymfonyQuestionHelper();
}

$answer = $this->questionHelper->ask($this->input, $this, $question);

$this->newLine();
if ($this->input->isInteractive()) {
$this->newLine();
$this->bufferedOutput->write("\n");
}

return $answer;
}

/**
* {@inheritdoc}
*/
public function writeln($messages, $type = self::OUTPUT_NORMAL)
{
parent::writeln($messages, $type);
$this->bufferedOutput->writeln($this->reduceBuffer($messages), $type);
}

/**
* {@inheritdoc}
*/
public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL)
{
parent::write($messages, $newline, $type);
$this->bufferedOutput->write($this->reduceBuffer($messages), $newline, $type);
}

/**
* {@inheritdoc}
*/
public function newLine($count = 1)
{
parent::newLine($count);
$this->bufferedOutput->write(str_repeat("\n", $count));
}

/**
* @return ProgressBar
*/
Expand All @@ -320,4 +371,33 @@ private function getTerminalWidth()

return $dimensions[0] ?: self::MAX_LINE_LENGTH;
}

private function autoPrependBlock()
{
$chars = substr(str_replace(PHP_EOL, "\n", $this->bufferedOutput->fetch()), -2);

if (false === $chars) {
return $this->newLine(); //empty history, so we should start with a new line.
}
//Prepend new line for each non LF chars (This means no blank line was output before)
$this->newLine(2 - substr_count($chars, "\n"));
}

private function autoPrependText()
{
$fetched = $this->bufferedOutput->fetch();
//Prepend new line if last char isn't EOL:
if ("\n" !== substr($fetched, -1)) {
$this->newLine();
}
}

private function reduceBuffer($messages)
{
// 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
return array_map(function ($value) {
return substr($value, -4);
}, array_merge(array($this->bufferedOutput->fetch()), (array) $messages));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

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

//Ensure has single blank line at start when using block element
return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyle($input, $output);
$output->caution('Lorem ipsum dolor sit amet');
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?p A3E2 hp

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

//Ensure has single blank line between titles and blocks
return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyle($input, $output);
$output->title('Title');
$output->warning('Lorem ipsum dolor sit amet');
$output->title('Title');
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

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

//Ensure has single blank line between blocks
return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyle($input, $output);
$output->warning('Warning');
$output->caution('Caution');
$output->error('Error');
$output->success('Success');
$output->note('Note');
$output->block('Custom block', 'CUSTOM', 'fg=white;bg=green', 'X ', true);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

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

//Ensure has single blank line between two titles
return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyle($input, $output);
$output->title('First title');
$output->title('Second title');
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

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

//Ensure has single blank line after any text and a title
return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyle($input, $output);

$output->write('Lorem ipsum dolor sit amet');
$output->title('First title');

$output->writeln('Lorem ipsum dolor sit amet');
$output->title('Second title');

$output->write('Lorem ipsum dolor sit amet');
$output->write('');
$output->title('Third title');

//Ensure edge case by appending empty strings to history:
$output->write('Lorem ipsum dolor sit amet');
$output->write(array('', '', ''));
$output->title('Fourth title');

//Ensure have manual control over number of blank lines:
$output->writeln('Lorem ipsum dolor sit amet');
$output->writeln(array('', '')); //Should append an extra blank line
$output->title('Fifth title');

$output->writeln('Lorem ipsum dolor sit amet');
$output->newLine(2); //Should append an extra blank line
$output->title('Fifth title');
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

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

//Ensure has proper line ending before outputing a text block like with SymfonyStyle::listing() or SymfonyStyle::text()
return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyle($input, $output);

$output->writeln('Lorem ipsum dolor sit amet');
$output->listing(array(
'Lorem ipsum dolor sit amet',
'consectetur adipiscing elit',
));

//Even using write:
$output->write('Lorem ipsum dolor sit amet');
$output->listing(array(
'Lorem ipsum dolor sit amet',
'consectetur adipiscing elit',
));

$output->write('Lorem ipsum dolor sit amet');
$output->text(array(
'Lorem ipsum dolor sit amet',
'consectetur adipiscing elit',
));
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

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

//Ensure has proper blank line after text block when using a block like with SymfonyStyle::success
return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyle($input, $output);

$output->listing(array(
'Lorem ipsum dolor sit amet',
'consectetur adipiscing elit',
));
$output->success('Lorem ipsum dolor sit amet');
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

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

//Ensure questions do not output anything when input is non-interactive
return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyle($input, $output);
$output->title('Title');
$output->askHidden('Hidden question');
$output->choice('Choice question with default', array('choice1', 'choice2'), 'choice1');
$output->confirm('Confirmation with yes default', true);
$output->text('Duis aute irure dolor in reprehenderit in voluptate velit esse');
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

! [CAUTION] Lorem ipsum dolor sit amet

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

Title
=====

[WARNING] Lorem ipsum dolor sit amet

Title
=====

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

[WARNING] Warning

! [CAUTION] Caution

[ERROR] Error

[OK] Success

! [NOTE] Note

X [CUSTOM] Custom block

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

First title
===========

Second title
============

Loading
0