mirror of
https://github.com/danog/psalm.git
synced 2025-01-21 21:31:13 +01:00
Use a horizontal progress bar with more than 1500 files
cc @iluuu1994
This commit is contained in:
parent
9d7cf66279
commit
dedd4aced0
@ -1,79 +1,37 @@
|
||||
<?php
|
||||
namespace Psalm\Progress;
|
||||
|
||||
class DefaultProgress extends Progress
|
||||
class DefaultProgress extends LongProgress
|
||||
{
|
||||
public const NUMBER_OF_COLUMNS = 60;
|
||||
|
||||
/** @var int|null */
|
||||
private $number_of_tasks;
|
||||
|
||||
/** @var int */
|
||||
private $progress = 0;
|
||||
|
||||
/** @var bool */
|
||||
private $print_failures = false;
|
||||
|
||||
public function __construct(bool $print_failures = true)
|
||||
{
|
||||
$this->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);
|
||||
}
|
||||
}
|
||||
|
82
src/Psalm/Progress/LongProgress.php
Normal file
82
src/Psalm/Progress/LongProgress.php
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
namespace Psalm\Progress;
|
||||
|
||||
class LongProgress extends Progress
|
||||
{
|
||||
public const NUMBER_OF_COLUMNS = 60;
|
||||
|
||||
/** @var int|null */
|
||||
protected $number_of_tasks;
|
||||
|
||||
/** @var int */
|
||||
protected $progress = 0;
|
||||
|
||||
/** @var bool */
|
||||
protected $print_failures = false;
|
||||
|
||||
public function __construct(bool $print_failures = true)
|
||||
{
|
||||
$this->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());
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user