From e580ad813ee7493cba609926ebee98841f6c9c07 Mon Sep 17 00:00:00 2001 From: Gareth Ellis Date: Tue, 1 Dec 2015 12:01:39 +0000 Subject: [PATCH] Add overwrite method to ConsoleOutput class --- lib/Cake/Console/ConsoleOutput.php | 41 ++++++++++++++++++- .../Test/Case/Console/ConsoleOutputTest.php | 21 ++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Console/ConsoleOutput.php b/lib/Cake/Console/ConsoleOutput.php index c2dd3278e54..765b7d26585 100644 --- a/lib/Cake/Console/ConsoleOutput.php +++ b/lib/Cake/Console/ConsoleOutput.php @@ -79,6 +79,14 @@ class ConsoleOutput { */ protected $_output; +/** + * The number of bytes last written to the output stream + * used when overwriting the previous message. + * + * @var int + */ + protected $_lastWritten = 0; + /** * The current output type. Manipulated with ConsoleOutput::outputAs(); * @@ -184,6 +192,36 @@ public function write($message, $newlines = 1) { return $this->_write($this->styleText($message . str_repeat(static::LF, $newlines))); } +/** + * Overwrite some already output text. + * + * Useful for building progress bars, or when you want to replace + * text already output to the screen with new text. + * + * **Warning** You cannot overwrite text that contains newlines. + * + * @param array|string $message The message to output. + * @param int $newlines Number of newlines to append. + * @param int $size The number of bytes to overwrite. Defaults to the + * length of the last message output. + * @return void + */ + public function overwrite($message, $newlines = 1, $size = null) + { + $size = $size ?: $this->_lastWritten; + // Output backspaces. + $this->write(str_repeat("\x08", $size), 0); + $newBytes = $this->write($message, 0); + // Fill any remaining bytes with spaces. + $fill = $size - $newBytes; + if ($fill > 0) { + $this->write(str_repeat(' ', $fill), 0); + } + if ($newlines) { + $this->write("", $newlines); + } + } + /** * Apply styling to text. * @@ -238,7 +276,8 @@ protected function _replaceTags($matches) { * @return bool success */ protected function _write($message) { - return fwrite($this->_output, $message); + $this->_lastWritten = fwrite($this->_output, $message); + return $this->_lastWritten; } /** diff --git a/lib/Cake/Test/Case/Console/ConsoleOutputTest.php b/lib/Cake/Test/Case/Console/ConsoleOutputTest.php index 5eabefd5847..1e24a223651 100644 --- a/lib/Cake/Test/Case/Console/ConsoleOutputTest.php +++ b/lib/Cake/Test/Case/Console/ConsoleOutputTest.php @@ -94,6 +94,27 @@ public function testWriteArray() { $this->output->write(array('Line', 'Line', 'Line')); } +/** + * test writing an array of messages. + * + * @return void + */ + public function testOverwrite() { + $testString = "Text"; + + $this->output->expects($this->at(0))->method('_write') + ->with($testString); + + $this->output->expects($this->at(1))->method('_write') + ->with(""); + + $this->output->expects($this->at(2))->method('_write') + ->with("Overwriting text"); + + $this->output->write($testString, 0); + $this->output->overwrite("Overwriting text"); + } + /** * test getting a style. *