From dedd4aced059418d2b3f8801cfa4a47c182c6a13 Mon Sep 17 00:00:00 2001 From: Brown Date: Thu, 30 May 2019 18:37:01 -0400 Subject: [PATCH] Use a horizontal progress bar with more than 1500 files cc @iluuu1994 --- src/Psalm/Progress/DefaultProgress.php | 84 +++++++------------------- src/Psalm/Progress/LongProgress.php | 82 +++++++++++++++++++++++++ src/Psalm/Progress/Progress.php | 11 ++++ 3 files changed, 114 insertions(+), 63 deletions(-) create mode 100644 src/Psalm/Progress/LongProgress.php diff --git a/src/Psalm/Progress/DefaultProgress.php b/src/Psalm/Progress/DefaultProgress.php index 5fbea9387..3c9826115 100644 --- a/src/Psalm/Progress/DefaultProgress.php +++ b/src/Psalm/Progress/DefaultProgress.php @@ -1,79 +1,37 @@ print_failures = $print_failures; - } - - public function startScanningFiles(): void - { - $this->write('Scanning files...' . "\n"); - } - - public function startAnalyzingFiles(): void - { - $this->write('Analyzing files...' . "\n\n"); - } - - public function start(int $number_of_tasks): void - { - $this->number_of_tasks = $number_of_tasks; - $this->progress = 0; - } + const TOO_MANY_FILES = 1500; public function taskDone(bool $successful): void { - if ($successful || !$this->print_failures) { - $this->write('_'); + if ($this->number_of_tasks > self::TOO_MANY_FILES) { + ++$this->progress; + + $expected_bars = round(($this->progress / $this->number_of_tasks) * self::NUMBER_OF_COLUMNS); + + $inner_progress = str_repeat(self::doesTerminalSupportUtf8() ? '░' : 'X', $expected_bars); + + if ($expected_bars !== self::NUMBER_OF_COLUMNS) { + $expected_bars--; + } + + $progress_bar = $inner_progress . str_repeat(' ', self::NUMBER_OF_COLUMNS - $expected_bars); + + $this->write($progress_bar . ' ' . $this->getOverview() . "\r"); } else { - $this->write('F'); + parent::taskDone($successful); } - - ++$this->progress; - - if (($this->progress % self::NUMBER_OF_COLUMNS) !== 0) { - return; - } - - $this->printOverview(); - $this->write(PHP_EOL); } public function finish(): void { - $this->write(PHP_EOL); - } - - private function printOverview(): void - { - if ($this->number_of_tasks === null) { - throw new \LogicException('Progress::start() should be called before Progress::startDone()'); + if ($this->number_of_tasks > self::TOO_MANY_FILES) { + $this->write(str_repeat(' ', self::NUMBER_OF_COLUMNS + strlen($this->getOverview()) + 1) . "\r"); + } else { + parent::finish(); } - - $leadingSpaces = 1 + strlen((string) $this->number_of_tasks) - strlen((string) $this->progress); - $percentage = round($this->progress / $this->number_of_tasks * 100); - $message = sprintf( - '%s%s / %s (%s%%)', - str_repeat(' ', $leadingSpaces), - $this->progress, - $this->number_of_tasks, - $percentage - ); - - $this->write($message); } } diff --git a/src/Psalm/Progress/LongProgress.php b/src/Psalm/Progress/LongProgress.php new file mode 100644 index 000000000..99af000de --- /dev/null +++ b/src/Psalm/Progress/LongProgress.php @@ -0,0 +1,82 @@ +print_failures = $print_failures; + } + + public function startScanningFiles(): void + { + $this->write('Scanning files...' . "\n"); + } + + public function startAnalyzingFiles(): void + { + $this->write('Analyzing files...' . "\n\n"); + } + + public function start(int $number_of_tasks): void + { + $this->number_of_tasks = $number_of_tasks; + $this->progress = 0; + } + + public function taskDone(bool $successful): void + { + if ($successful || !$this->print_failures) { + $this->write(self::doesTerminalSupportUtf8() ? '▒' : '_'); + } else { + $this->write('F'); + } + + ++$this->progress; + + if (($this->progress % self::NUMBER_OF_COLUMNS) !== 0) { + return; + } + + $this->printOverview(); + $this->write(PHP_EOL); + } + + public function finish(): void + { + $this->write(PHP_EOL); + } + + protected function getOverview() : string + { + if ($this->number_of_tasks === null) { + throw new \LogicException('Progress::start() should be called before Progress::startDone()'); + } + + $leadingSpaces = 1 + strlen((string) $this->number_of_tasks) - strlen((string) $this->progress); + $percentage = round($this->progress / $this->number_of_tasks * 100); + return sprintf( + '%s%s / %s (%s%%)', + str_repeat(' ', $leadingSpaces), + $this->progress, + $this->number_of_tasks, + $percentage + ); + } + + private function printOverview(): void + { + $this->write($this->getOverview()); + } +} diff --git a/src/Psalm/Progress/Progress.php b/src/Psalm/Progress/Progress.php index 529cfd8b8..6577fafc0 100644 --- a/src/Psalm/Progress/Progress.php +++ b/src/Psalm/Progress/Progress.php @@ -36,4 +36,15 @@ abstract class Progress { fwrite(STDERR, $message); } + + protected static function doesTerminalSupportUtf8() : bool + { + if (\strtoupper(\substr(PHP_OS, 0, 3)) === 'WIN') { + if (!\function_exists('sapi_windows_cp_is_utf8') || !\sapi_windows_cp_is_utf8()) { + return false; + } + } + + return true; + } }