Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13983642
D14136.id34158.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
13 KB
Referenced Files
None
Subscribers
None
D14136.id34158.diff
View Options
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -125,14 +125,18 @@
'PhutilCodeSnippetContextFreeGrammar' => 'grammar/code/PhutilCodeSnippetContextFreeGrammar.php',
'PhutilCommandString' => 'xsprintf/PhutilCommandString.php',
'PhutilConsole' => 'console/PhutilConsole.php',
+ 'PhutilConsoleBlock' => 'console/view/PhutilConsoleBlock.php',
+ 'PhutilConsoleConcatenatedView' => 'console/view/PhutilConsoleConcatenatedView.php',
'PhutilConsoleFormatter' => 'console/PhutilConsoleFormatter.php',
+ 'PhutilConsoleList' => 'console/view/PhutilConsoleList.php',
'PhutilConsoleMessage' => 'console/PhutilConsoleMessage.php',
'PhutilConsoleProgressBar' => 'console/PhutilConsoleProgressBar.php',
'PhutilConsoleServer' => 'console/PhutilConsoleServer.php',
'PhutilConsoleServerChannel' => 'console/PhutilConsoleServerChannel.php',
'PhutilConsoleStdinNotInteractiveException' => 'console/PhutilConsoleStdinNotInteractiveException.php',
'PhutilConsoleSyntaxHighlighter' => 'markup/syntax/highlighter/PhutilConsoleSyntaxHighlighter.php',
- 'PhutilConsoleTable' => 'console/PhutilConsoleTable.php',
+ 'PhutilConsoleTable' => 'console/view/PhutilConsoleTable.php',
+ 'PhutilConsoleView' => 'console/view/PhutilConsoleView.php',
'PhutilConsoleWrapTestCase' => 'console/__tests__/PhutilConsoleWrapTestCase.php',
'PhutilContextFreeGrammar' => 'grammar/PhutilContextFreeGrammar.php',
'PhutilCowsay' => 'utils/PhutilCowsay.php',
@@ -307,6 +311,7 @@
'PhutilRemarkupUnderlineRule' => 'markup/engine/remarkup/markuprule/PhutilRemarkupUnderlineRule.php',
'PhutilRope' => 'utils/PhutilRope.php',
'PhutilRopeTestCase' => 'utils/__tests__/PhutilRopeTestCase.php',
+ 'PhutilSafeConsoleString' => 'console/view/PhutilSafeConsoleString.php',
'PhutilSafeHTML' => 'markup/PhutilSafeHTML.php',
'PhutilSafeHTMLProducerInterface' => 'markup/PhutilSafeHTMLProducerInterface.php',
'PhutilSafeHTMLTestCase' => 'markup/__tests__/PhutilSafeHTMLTestCase.php',
@@ -635,14 +640,18 @@
'PhutilCodeSnippetContextFreeGrammar' => 'PhutilContextFreeGrammar',
'PhutilCommandString' => 'Phobject',
'PhutilConsole' => 'Phobject',
+ 'PhutilConsoleBlock' => 'PhutilConsoleView',
+ 'PhutilConsoleConcatenatedView' => 'PhutilConsoleView',
'PhutilConsoleFormatter' => 'Phobject',
+ 'PhutilConsoleList' => 'PhutilConsoleView',
'PhutilConsoleMessage' => 'Phobject',
'PhutilConsoleProgressBar' => 'Phobject',
'PhutilConsoleServer' => 'Phobject',
'PhutilConsoleServerChannel' => 'PhutilChannelChannel',
'PhutilConsoleStdinNotInteractiveException' => 'Exception',
'PhutilConsoleSyntaxHighlighter' => 'Phobject',
- 'PhutilConsoleTable' => 'Phobject',
+ 'PhutilConsoleTable' => 'PhutilConsoleView',
+ 'PhutilConsoleView' => 'Phobject',
'PhutilConsoleWrapTestCase' => 'PhutilTestCase',
'PhutilContextFreeGrammar' => 'Phobject',
'PhutilCowsay' => 'Phobject',
@@ -818,6 +827,7 @@
'PhutilRemarkupUnderlineRule' => 'PhutilRemarkupRule',
'PhutilRope' => 'Phobject',
'PhutilRopeTestCase' => 'PhutilTestCase',
+ 'PhutilSafeConsoleString' => 'Phobject',
'PhutilSafeHTML' => 'Phobject',
'PhutilSafeHTMLTestCase' => 'PhutilTestCase',
'PhutilSaturateStdoutDaemon' => 'PhutilTortureTestDaemon',
diff --git a/src/console/view/PhutilConsoleBlock.php b/src/console/view/PhutilConsoleBlock.php
new file mode 100644
--- /dev/null
+++ b/src/console/view/PhutilConsoleBlock.php
@@ -0,0 +1,45 @@
+<?php
+
+final class PhutilConsoleBlock extends PhutilConsoleView {
+
+ private $items = array();
+
+ public function addParagraph($item) {
+ $this->items[] = array(
+ 'type' => 'paragraph',
+ 'item' => $item,
+ );
+ return $this;
+ }
+
+ public function addList(PhutilConsoleList $list) {
+ $this->items[] = array(
+ 'type' => 'list',
+ 'item' => $list,
+ );
+ return $this;
+ }
+
+ protected function drawView() {
+ $output = array();
+
+ foreach ($this->items as $spec) {
+ $type = $spec['type'];
+ $item = $spec['item'];
+
+ switch ($type) {
+ case 'paragraph':
+ $item = phutil_console_wrap($item)."\n";
+ break;
+ case 'list':
+ $item = $item;
+ break;
+ }
+
+ $output[] = $item;
+ }
+
+ return $this->drawLines($output);
+ }
+
+}
diff --git a/src/console/view/PhutilConsoleConcatenatedView.php b/src/console/view/PhutilConsoleConcatenatedView.php
new file mode 100644
--- /dev/null
+++ b/src/console/view/PhutilConsoleConcatenatedView.php
@@ -0,0 +1,22 @@
+<?php
+
+final class PhutilConsoleConcatenatedView extends PhutilConsoleView {
+
+ private $items = array();
+
+ public function addItem($item) {
+ $this->items[] = $item;
+ return $this;
+ }
+
+ protected function drawView() {
+ $output = array();
+
+ foreach ($this->items as $item) {
+ $output[] = $this->flattenView($item);
+ }
+
+ return implode('', $output);
+ }
+
+}
diff --git a/src/console/view/PhutilConsoleList.php b/src/console/view/PhutilConsoleList.php
new file mode 100644
--- /dev/null
+++ b/src/console/view/PhutilConsoleList.php
@@ -0,0 +1,42 @@
+<?php
+
+final class PhutilConsoleList extends PhutilConsoleView {
+
+ private $items = array();
+ private $wrap = true;
+
+ public function addItem($item) {
+ $this->items[] = $item;
+ return $this;
+ }
+
+ public function addItems(array $items) {
+ foreach ($items as $item) {
+ $this->addItem($item);
+ }
+ return $this;
+ }
+
+ public function getItems() {
+ return $this->items;
+ }
+
+ public function setWrap($wrap) {
+ $this->wrap = $wrap;
+ return $this;
+ }
+
+ protected function drawView() {
+ $output = array();
+ foreach ($this->getItems() as $item) {
+ if ($this->wrap) {
+ $item = phutil_console_wrap($item, 8);
+ }
+ $item = ' - '.$item;
+ $output[] = $item;
+ }
+
+ return $this->drawLines($output);
+ }
+
+}
diff --git a/src/console/PhutilConsoleTable.php b/src/console/view/PhutilConsoleTable.php
rename from src/console/PhutilConsoleTable.php
rename to src/console/view/PhutilConsoleTable.php
--- a/src/console/PhutilConsoleTable.php
+++ b/src/console/view/PhutilConsoleTable.php
@@ -22,7 +22,7 @@
* ->setBorders(true)
* ->draw();
*/
-final class PhutilConsoleTable extends Phobject {
+final class PhutilConsoleTable extends PhutilConsoleView {
private $columns = array();
private $data = array();
@@ -30,30 +30,15 @@
private $borders = false;
private $padding = 1;
private $showHeader = true;
- private $console;
const ALIGN_LEFT = 'left';
const ALIGN_CENTER = 'center';
const ALIGN_RIGHT = 'right';
-/* -( Console )------------------------------------------------------------ */
-
- protected function getConsole() {
- if ($this->console) {
- return $this->console;
- }
- return PhutilConsole::getConsole();
- }
-
- public function setConsole(PhutilConsole $console) {
- $this->console = $console;
- return $this;
- }
-
-
/* -( Configuration )------------------------------------------------------ */
+
public function setBorders($borders) {
$this->borders = $borders;
return $this;
@@ -103,19 +88,19 @@
/* -( Drawing )------------------------------------------------------------ */
- public function draw() {
- $console = $this->getConsole();
-
- $console->writeOut('%s', $this->getHeader());
- $console->writeOut('%s', $this->getBody());
- $console->writeOut('%s', $this->getFooter());
+ protected function drawView() {
+ return $this->drawLines(
+ array_merge(
+ $this->getHeader(),
+ $this->getBody(),
+ $this->getFooter()));
}
private function getHeader() {
- $output = '';
+ $output = array();
if ($this->borders) {
- $output .= $this->formatSeparator('=');
+ $output[] = $this->formatSeparator('=');
}
if (!$this->showHeader) {
@@ -133,22 +118,27 @@
idx($column, 'align', self::ALIGN_LEFT));
}
- $columns[] = PhutilConsoleFormatter::formatString(
+ $header = PhutilConsoleFormatter::formatString(
'**%s**',
$column_str);
+
+ // TODO: This is gross but we don't have any helper functions for
+ // building PhutilSafeConsoleStrings yet.
+
+ $columns[] = new PhutilSafeConsoleString($header);
}
- $output .= $this->formatRow($columns);
+ $output[] = $this->formatRow($columns);
if ($this->borders) {
- $output .= $this->formatSeparator('=');
+ $output[] = $this->formatSeparator('=');
}
return $output;
}
private function getBody() {
- $output = '';
+ $output = array();
foreach ($this->data as $data) {
$columns = array();
@@ -164,14 +154,14 @@
}
}
- $output .= $this->formatRow($columns);
+ $output[] = $this->formatRow($columns);
}
return $output;
}
private function getFooter() {
- $output = '';
+ $output = array();
if ($this->borders) {
$columns = array();
@@ -180,7 +170,11 @@
$columns[] = str_repeat('=', $this->getWidth($column));
}
- $output .= '+'.implode('+', $columns)."+\n";
+ $output[] = array(
+ '+',
+ $this->implode('+', $columns),
+ '+',
+ );
}
return $output;
@@ -272,9 +266,13 @@
if ($this->borders) {
$separator = $padding.'|'.$padding;
- return '|'.$padding.implode($separator, $columns).$padding."|\n";
+ return array(
+ '|'.$padding,
+ $this->implode($separator, $columns),
+ $padding.'|',
+ );
} else {
- return implode($padding, $columns)."\n";
+ return $this->implode($padding, $columns);
}
}
@@ -291,7 +289,11 @@
$columns[] = str_repeat($string, $this->getWidth($column));
}
- return $separator.implode($separator, $columns).$separator."\n";
+ return array(
+ $separator,
+ $this->implode($separator, $columns),
+ $separator,
+ );
}
}
diff --git a/src/console/view/PhutilConsoleView.php b/src/console/view/PhutilConsoleView.php
new file mode 100644
--- /dev/null
+++ b/src/console/view/PhutilConsoleView.php
@@ -0,0 +1,116 @@
+<?php
+
+abstract class PhutilConsoleView extends Phobject {
+
+ private $console;
+
+ abstract protected function drawView();
+
+ final public function setConsole(PhutilConsole $console) {
+ $this->console = $console;
+ return $this;
+ }
+
+ final public function getConsole() {
+ if ($this->console) {
+ return $this->console;
+ }
+ return PhutilConsole::getConsole();
+ }
+
+
+ /**
+ * Draw a view to the console.
+ *
+ * @return this
+ * @task draw
+ */
+ final public function draw() {
+ $string = $this->drawConsoleString();
+
+ $console = $this->getConsole();
+ $console->writeOut('%s', $string);
+
+ return $this;
+ }
+
+
+ /**
+ * Draw a view to a string and return it.
+ *
+ * @return string Console-printable string.
+ * @task draw
+ */
+ final public function drawConsoleString() {
+ $view = $this->drawView();
+ $parts = $this->reduceView($view);
+
+ $out = array();
+ foreach ($parts as $part) {
+ if ($part instanceof PhutilSafeConsoleString) {
+ $out[] = $part->getConsoleStringContent();
+ } else {
+ $out[] = phutil_console_format('%s', $part);
+ }
+ }
+
+ return implode('', $out);
+ }
+
+
+ /**
+ * Reduce a view to a list of simple, unnested parts.
+ *
+ * @param wild Any drawable view.
+ * @return list<wild> List of unnested drawables.
+ * @task draw
+ */
+ private function reduceView($view) {
+ if ($view instanceof PhutilConsoleView) {
+ $view = $view->drawView();
+ return $this->reduceView($view);
+ }
+
+ if (is_array($view)) {
+ $parts = array();
+ foreach ($view as $item) {
+ foreach ($this->reduceView($item) as $part) {
+ $parts[] = $part;
+ }
+ }
+ return $parts;
+ }
+
+ return array($view);
+ }
+
+/* -( Drawing Utilities )-------------------------------------------------- */
+
+
+ /**
+ * @param list<wild> List of views, one per line.
+ * @return wild Each view rendered on a separate line.
+ */
+ final protected function drawLines(array $parts) {
+ $result = array();
+ foreach ($parts as $part) {
+ if ($part !== null) {
+ $result[] = $part;
+ $result[] = "\n";
+ }
+ }
+
+ return $result;
+ }
+
+ final protected function implode($separator, array $items) {
+ $result = array();
+ foreach ($items as $item) {
+ $result[] = $item;
+ $result[] = $separator;
+ }
+ array_pop($result);
+ return $result;
+ }
+
+}
diff --git a/src/console/view/PhutilSafeConsoleString.php b/src/console/view/PhutilSafeConsoleString.php
new file mode 100644
--- /dev/null
+++ b/src/console/view/PhutilSafeConsoleString.php
@@ -0,0 +1,15 @@
+<?php
+
+final class PhutilSafeConsoleString extends Phobject {
+
+ private $content;
+
+ public function __construct($content) {
+ $this->content = (string)$content;
+ }
+
+ public function getConsoleStringContent() {
+ return $this->content;
+ }
+
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Oct 21, 7:48 AM (2 w, 23 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6738802
Default Alt Text
D14136.id34158.diff (13 KB)
Attached To
Mode
D14136: Introduce PhutilConsoleView for rendering elements to the console
Attached
Detach File
Event Timeline
Log In to Comment