Page MenuHomePhabricator

D18669.id44823.diff
No OneTemporary

D18669.id44823.diff

diff --git a/scripts/__init_script__.php b/scripts/__init_script__.php
--- a/scripts/__init_script__.php
+++ b/scripts/__init_script__.php
@@ -90,6 +90,9 @@
$handler = new PhutilBacktraceSignalHandler();
$router->installHandler('phutil.backtrace', $handler);
+
+ $handler = new PhutilConsoleMetricsSignalHandler();
+ $router->installHandler('phutil.winch', $handler);
}
__phutil_init_script__();
diff --git a/scripts/test/progress_bar.php b/scripts/test/progress_bar.php
--- a/scripts/test/progress_bar.php
+++ b/scripts/test/progress_bar.php
@@ -43,6 +43,19 @@
echo pht('Caught exception!')."\n";
}
+echo "\n".pht(
+ "RESIZING BARS\n".
+ "If you resize the window while a progress bars draws, it should more or ".
+ "less detect the change.");
+
+$n = 1024;
+$bar = id(new PhutilConsoleProgressBar())
+ ->setTotal($n);
+for ($ii = 0; $ii < $n; $ii++) {
+ $bar->update(1);
+ usleep(10000);
+}
+$bar->done();
function run_interrupt_bar() {
$bar = id(new PhutilConsoleProgressBar())
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
@@ -177,6 +177,8 @@
'PhutilConsoleList' => 'console/view/PhutilConsoleList.php',
'PhutilConsoleLogLine' => 'console/view/PhutilConsoleLogLine.php',
'PhutilConsoleMessage' => 'console/PhutilConsoleMessage.php',
+ 'PhutilConsoleMetrics' => 'console/PhutilConsoleMetrics.php',
+ 'PhutilConsoleMetricsSignalHandler' => 'future/exec/PhutilConsoleMetricsSignalHandler.php',
'PhutilConsoleProgressBar' => 'console/PhutilConsoleProgressBar.php',
'PhutilConsoleServer' => 'console/PhutilConsoleServer.php',
'PhutilConsoleServerChannel' => 'console/PhutilConsoleServerChannel.php',
@@ -799,6 +801,8 @@
'PhutilConsoleList' => 'PhutilConsoleView',
'PhutilConsoleLogLine' => 'PhutilConsoleView',
'PhutilConsoleMessage' => 'Phobject',
+ 'PhutilConsoleMetrics' => 'Phobject',
+ 'PhutilConsoleMetricsSignalHandler' => 'PhutilSignalHandler',
'PhutilConsoleProgressBar' => 'Phobject',
'PhutilConsoleServer' => 'Phobject',
'PhutilConsoleServerChannel' => 'PhutilChannelChannel',
diff --git a/src/console/PhutilConsoleMetrics.php b/src/console/PhutilConsoleMetrics.php
new file mode 100644
--- /dev/null
+++ b/src/console/PhutilConsoleMetrics.php
@@ -0,0 +1,62 @@
+<?php
+
+final class PhutilConsoleMetrics extends Phobject {
+
+ const DEFAULT_CONSOLE = 'default';
+
+ private static $consoles = array();
+
+ private $width = false;
+
+ public static function getNamedConsole($key) {
+ if (!isset(self::$consoles[$key])) {
+ self::$consoles[$key] = new self();
+ }
+
+ return self::$consoles[$key];
+ }
+
+ public static function getDefaultConsole() {
+ return self::getNamedConsole(self::DEFAULT_CONSOLE);
+ }
+
+ public function didGetWINCHSignal() {
+ // When we receive a "WINCH" ("WINdow CHange") signal, clear the cached
+ // information we have about the terminal.
+ $this->width = false;
+
+ return $this;
+ }
+
+ public function getTerminalWidth() {
+ if ($this->width === false) {
+ $this->width = $this->computeTerminalWidth();
+ }
+
+ return $this->width;
+ }
+
+ private function computeTerminalWidth() {
+ if (phutil_is_windows()) {
+ // TODO: Figure out how to do this on Windows.
+ return null;
+ }
+
+ $tmp = new TempFile();
+ $err = id(new PhutilExecPassthru('tput cols > %s', $tmp))
+ ->resolve();
+ $stdout = Filesystem::readFile($tmp);
+ unset($tmp);
+
+ if ($err) {
+ return null;
+ }
+
+ $width = (int)trim($stdout);
+ if ($width > 0) {
+ return $width;
+ }
+
+ return null;
+ }
+}
diff --git a/src/console/format.php b/src/console/format.php
--- a/src/console/format.php
+++ b/src/console/format.php
@@ -204,35 +204,6 @@
* @return int|null Terminal width in characters, or null on failure.
*/
function phutil_console_get_terminal_width() {
- static $width;
-
- if ($width === null) {
- if (phutil_is_windows()) {
- // TODO: Figure out how to get this working in Windows.
- return null;
- }
-
- $tmp = new TempFile();
-
- // NOTE: We can't just execute this because it won't be connected to a TTY
- // if we do.
- $err = phutil_passthru('tput cols > %s', $tmp);
-
- if ($err) {
- return null;
- }
-
- try {
- $cols = Filesystem::readFile($tmp);
- } catch (FilesystemException $ex) {
- return null;
- }
-
- $width = (int)$cols;
- if (!$width) {
- $width = null;
- }
- }
-
- return $width;
+ return PhutilConsoleMetrics::getDefaultConsole()
+ ->getTerminalWidth();
}
diff --git a/src/future/exec/PhutilConsoleMetricsSignalHandler.php b/src/future/exec/PhutilConsoleMetricsSignalHandler.php
new file mode 100644
--- /dev/null
+++ b/src/future/exec/PhutilConsoleMetricsSignalHandler.php
@@ -0,0 +1,14 @@
+<?php
+
+final class PhutilConsoleMetricsSignalHandler extends PhutilSignalHandler {
+
+ public function canHandleSignal(PhutilSignalRouter $router, $signo) {
+ return ($signo === SIGWINCH);
+ }
+
+ public function handleSignal(PhutilSignalRouter $router, $signo) {
+ PhutilConsoleMetrics::getDefaultConsole()
+ ->didGetWINCHSignal();
+ }
+
+}
diff --git a/src/future/exec/PhutilSignalRouter.php b/src/future/exec/PhutilSignalRouter.php
--- a/src/future/exec/PhutilSignalRouter.php
+++ b/src/future/exec/PhutilSignalRouter.php
@@ -18,6 +18,7 @@
if (function_exists('pcntl_signal')) {
pcntl_signal(SIGHUP, array($router, 'routeSignal'));
pcntl_signal(SIGTERM, array($router, 'routeSignal'));
+ pcntl_signal(SIGWINCH, array($router, 'routeSignal'));
}
self::$router = $router;

File Metadata

Mime Type
text/plain
Expires
Sat, May 18, 11:20 PM (2 w, 1 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6301363
Default Alt Text
D18669.id44823.diff (5 KB)

Event Timeline