diff --git a/src/mako/cli/output/components/Spinner.php b/src/mako/cli/output/components/Spinner.php index ae896b85a..d6ce4fed6 100644 --- a/src/mako/cli/output/components/Spinner.php +++ b/src/mako/cli/output/components/Spinner.php @@ -17,7 +17,6 @@ use function posix_getpid; use function posix_getppid; use function posix_kill; -use function sprintf; use function usleep; /** @@ -51,7 +50,7 @@ protected function canFork(): bool /** * Draws the spinner. */ - protected function spinner(string $message, string $template): void + protected function spinner(string $message): void { $i = 0; @@ -62,7 +61,7 @@ protected function spinner(string $message, string $template): void $timeBetweenRedraw = $this->frames->getTimeBetweenRedraw(); while (true) { - $this->output->write("\r" . sprintf($template, $frames[$i++ % $frameCount]) . " {$message}"); + $this->output->write("\r" . $frames[$i++ % $frameCount] . " {$message}"); if (posix_kill(posix_getpid(), 0) === false) { break; @@ -79,7 +78,7 @@ protected function spinner(string $message, string $template): void /** * Draws the spinner. */ - public function spin(string $message, callable $callback, string $template = '%s'): mixed + public function spin(string $message, callable $callback): mixed { $result = null; @@ -110,7 +109,7 @@ public function spin(string $message, callable $callback, string $template = '%s else { // We're in the child process so we'll display the spinner - $this->spinner($message, $template); + $this->spinner($message); } $this->output->getCursor()->restore(); diff --git a/src/mako/cli/output/components/progress/ProgressBar.php b/src/mako/cli/output/components/progress/ProgressBar.php index a32134a87..96436cb4d 100644 --- a/src/mako/cli/output/components/progress/ProgressBar.php +++ b/src/mako/cli/output/components/progress/ProgressBar.php @@ -7,6 +7,8 @@ namespace mako\cli\output\components\progress; +use function sprintf; + /** * Progress bar. */ @@ -22,12 +24,21 @@ class ProgressBar */ protected const string FILLED = '█'; + /** + * Constructor. + */ + public function __construct( + protected string $emptyTemplate = '%s', + protected string $filledTemplate = '%s' + ) { + } + /** * Returns the empty progress bar character. */ public function getEmpty(): string { - return static::EMPTY; + return sprintf($this->emptyTemplate, static::EMPTY); } /** @@ -35,6 +46,6 @@ public function getEmpty(): string */ public function getFilled(): string { - return static::FILLED; + return sprintf($this->filledTemplate, static::FILLED); } } diff --git a/src/mako/cli/output/components/spinner/Frames.php b/src/mako/cli/output/components/spinner/Frames.php index 9b0ecedf1..9ae348cf9 100644 --- a/src/mako/cli/output/components/spinner/Frames.php +++ b/src/mako/cli/output/components/spinner/Frames.php @@ -7,6 +7,9 @@ namespace mako\cli\output\components\spinner; +use function array_map; +use function sprintf; + /** * Frames. */ @@ -22,12 +25,20 @@ class Frames */ protected const array FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']; + /** + * Constructor. + */ + public function __construct( + protected string $template = '%s' + ) { + } + /** * Returns the spinner frames. */ public function getFrames(): array { - return static::FRAMES; + return array_map(fn ($frame) => sprintf($this->template, $frame), static::FRAMES); } /** diff --git a/src/mako/reactor/traits/CommandHelperTrait.php b/src/mako/reactor/traits/CommandHelperTrait.php index e2ab8d46b..164e88375 100644 --- a/src/mako/reactor/traits/CommandHelperTrait.php +++ b/src/mako/reactor/traits/CommandHelperTrait.php @@ -17,6 +17,7 @@ use mako\cli\output\components\Countdown; use mako\cli\output\components\OrderedList; use mako\cli\output\components\Progress; +use mako\cli\output\components\progress\ProgressBar; use mako\cli\output\components\ProgressIterator; use mako\cli\output\components\Spinner; use mako\cli\output\components\spinner\Frames; @@ -115,14 +116,15 @@ protected function progressBar(int $items, float $minTimeBetweenRedraw = 0.1, ?s /** * Draws a progress bar and returns a progress instance. */ - protected function progress(int $itemCount, string $description = '', int $width = 50, float $minTimeBetweenRedraw = 0.1): Progress + protected function progress(int $itemCount, string $description = '', int $width = 50, float $minTimeBetweenRedraw = 0.1, ProgressBar $progressBar = new ProgressBar): Progress { $progressBar = new Progress( $this->output, $itemCount, $description, $width, - $minTimeBetweenRedraw + $minTimeBetweenRedraw, + $progressBar ); $progressBar->draw(); @@ -133,23 +135,24 @@ protected function progress(int $itemCount, string $description = '', int $width /** * Returns a progress iterator instance. */ - protected function progressIterator(array|(Countable&Traversable) $items, string $description = '', int $width = 50, float $minTimeBetweenRedraw = 0.1): ProgressIterator + protected function progressIterator(array|(Countable&Traversable) $items, string $description = '', int $width = 50, float $minTimeBetweenRedraw = 0.1, ProgressBar $progressBar = new ProgressBar): ProgressIterator { return new ProgressIterator( $this->output, $items, $description, $width, - $minTimeBetweenRedraw + $minTimeBetweenRedraw, + $progressBar ); } /** * Draws a spinner while executing the callback. */ - protected function spinner(string $message, callable $callback, string $template = '%s', Frames $frames = new Frames): void + protected function spinner(string $message, callable $callback, Frames $frames = new Frames): void { - (new Spinner($this->output, $frames))->spin($message, $callback, $template); + (new Spinner($this->output, $frames))->spin($message, $callback); } /** diff --git a/tests/unit/cli/output/components/progress/ProgressBarTest.php b/tests/unit/cli/output/components/progress/ProgressBarTest.php new file mode 100644 index 000000000..6d8ad3b85 --- /dev/null +++ b/tests/unit/cli/output/components/progress/ProgressBarTest.php @@ -0,0 +1,40 @@ +assertSame('─', $progressBar->getEmpty()); + + $this->assertSame('█', $progressBar->getFilled()); + } + + /** + * + */ + public function testWithCustomTemplate(): void + { + $progressBar = new ProgressBar('x%sx', 'y%sy'); + + $this->assertSame('x─x', $progressBar->getEmpty()); + + $this->assertSame('y█y', $progressBar->getFilled()); + } +} diff --git a/tests/unit/cli/output/components/spinner/FramesTest.php b/tests/unit/cli/output/components/spinner/FramesTest.php new file mode 100644 index 000000000..673cb65ed --- /dev/null +++ b/tests/unit/cli/output/components/spinner/FramesTest.php @@ -0,0 +1,36 @@ +assertSame(['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'], $frames->getFrames()); + } + + /** + * + */ + public function testWithCustomTemplate(): void + { + $frames = new Frames('x%sx'); + + $this->assertSame(['x⠋x', 'x⠙x', 'x⠹x', 'x⠸x', 'x⠼x', 'x⠴x', 'x⠦x', 'x⠧x', 'x⠇x', 'x⠏x'], $frames->getFrames()); + } +}