diff --git a/src/ZM/Command/Command.php b/src/ZM/Command/Command.php index d5e54c5f..c685a5fd 100644 --- a/src/ZM/Command/Command.php +++ b/src/ZM/Command/Command.php @@ -4,15 +4,14 @@ declare(strict_types=1); namespace ZM\Command; -use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\ConsoleOutputInterface; -use Symfony\Component\Console\Output\ConsoleSectionOutput; use Symfony\Component\Console\Output\OutputInterface; -use ZM\Exception\ZMException; abstract class Command extends \Symfony\Component\Console\Command\Command { + use CommandInteractTrait; + /** * 输入 */ @@ -25,115 +24,6 @@ abstract class Command extends \Symfony\Component\Console\Command\Command */ protected OutputInterface $output; - /** - * 输出一段文本,默认样式 - * - * @param string $message 要输出的文本 - * @param bool $newline 是否在文本后换行 - * @see OutputInterface::write() - */ - public function write(string $message, bool $newline = true): void - { - $this->output->write($message, $newline); - } - - /** - * 输出文本,一般用于提示信息 - * - * @param string $message 要输出的文本 - * @param bool $newline 是否在文本后换行 - */ - public function info(string $message, bool $newline = true): void - { - $this->write("{$message}", $newline); - } - - /** - * 输出文本,一般用于错误信息 - * - * @param string $message 要输出的文本 - * @param bool $newline 是否在文本后换行 - */ - public function error(string $message, bool $newline = true): void - { - $this->write("{$message}", $newline); - } - - /** - * 输出文本,一般用于警告或附注信息 - * - * @param string $message 要输出的文本 - * @param bool $newline 是否在文本后换行 - */ - public function comment(string $message, bool $newline = true): void - { - $this->write("{$message}", $newline); - } - - /** - * 输出文本,一般用于提问信息 - * - * @param string $message 要输出的文本 - * @param bool $newline 是否在文本后换行 - */ - public function question(string $message, bool $newline = true): void - { - $this->write("{$message}", $newline); - } - - /** - * 输出文本,一般用于详细信息 - * - * @param string $message 要输出的文本 - * @param bool $newline 是否在文本后换行 - */ - public function detail(string $message, bool $newline = true): void - { - $this->write("{$message}", $newline); - } - - /** - * 输出一个区块,区块内内容可以覆写 - * - * 此功能需要 $output 为 {@see ConsoleOutputInterface} 类型 - * - * @param string $message 作为标题的文本 - * @param callable $callback 回调函数,接收一个参数,类型为 {@see ConsoleSectionOutput} - */ - public function section(string $message, callable $callback): void - { - $output = $this->output; - if (!$output instanceof ConsoleOutputInterface) { - throw new \LogicException('Section 功能只能在 ConsoleOutputInterface 中使用'); - } - - $this->info($message); - $section = $output->section(); - try { - $callback($section); - } catch (ZMException $e) { - $this->error($e->getMessage()); - exit(self::FAILURE); - } - } - - /** - * 获取一个进度条实例 - * - * @param int $max 最大进度值,可以稍后再设置 - */ - public function progress(int $max = 0): ProgressBar - { - $progress = new ProgressBar($this->output, $max); - $progress->setBarCharacter('⚬'); - $progress->setEmptyBarCharacter('⚬'); - $progress->setProgressCharacter('➤'); - $progress->setFormat( - "%current%/%max% [%bar%] %percent:3s%%\n🪅 %estimated:-20s% %memory:20s%" . PHP_EOL - ); - return $progress; - } - /** * {@inheritdoc} * @internal 不建议覆写此方法,建议使用 {@see handle()} 方法 diff --git a/src/ZM/Command/CommandInteractTrait.php b/src/ZM/Command/CommandInteractTrait.php new file mode 100644 index 00000000..e85dc4fe --- /dev/null +++ b/src/ZM/Command/CommandInteractTrait.php @@ -0,0 +1,155 @@ +output->write($message, $newline); + } + + /** + * 输出文本,一般用于提示信息 + * + * @param string $message 要输出的文本 + * @param bool $newline 是否在文本后换行 + */ + protected function info(string $message, bool $newline = true): void + { + $this->write("{$message}", $newline); + } + + /** + * 输出文本,一般用于错误信息 + * + * @param string $message 要输出的文本 + * @param bool $newline 是否在文本后换行 + */ + protected function error(string $message, bool $newline = true): void + { + $this->write("{$message}", $newline); + } + + /** + * 输出文本,一般用于警告或附注信息 + * + * @param string $message 要输出的文本 + * @param bool $newline 是否在文本后换行 + */ + protected function comment(string $message, bool $newline = true): void + { + $this->write("{$message}", $newline); + } + + /** + * 输出文本,一般用于提问信息 + * + * @param string $message 要输出的文本 + * @param bool $newline 是否在文本后换行 + */ + protected function question(string $message, bool $newline = true): void + { + $this->write("{$message}", $newline); + } + + /** + * 输出文本,一般用于详细信息 + * + * @param string $message 要输出的文本 + * @param bool $newline 是否在文本后换行 + */ + protected function detail(string $message, bool $newline = true): void + { + $this->write("{$message}", $newline); + } + + /** + * 输出一个区块,区块内内容可以覆写 + * + * 此功能需要 $output 为 {@see ConsoleOutputInterface} 类型 + * + * @param string $message 作为标题的文本 + * @param callable $callback 回调函数,接收一个参数,类型为 {@see ConsoleSectionOutput} + */ + protected function section(string $message, callable $callback): void + { + $output = $this->output; + if (!$output instanceof ConsoleOutputInterface) { + throw new \LogicException('Section 功能只能在 ConsoleOutputInterface 中使用'); + } + + $this->info($message); + $section = $output->section(); + try { + $callback($section); + } catch (ZMException $e) { + $this->error($e->getMessage()); + exit(self::FAILURE); + } + } + + /** + * 获取一个进度条实例 + * + * @param int $max 最大进度值,可以稍后再设置 + */ + protected function progress(int $max = 0): ProgressBar + { + $progress = new ProgressBar($this->output, $max); + $progress->setBarCharacter('⚬'); + $progress->setEmptyBarCharacter('⚬'); + $progress->setProgressCharacter('➤'); + $progress->setFormat( + "%current%/%max% [%bar%] %percent:3s%%\n🪅 %estimated:-20s% %memory:20s%" . PHP_EOL + ); + return $progress; + } + + /** + * 询问用户是否确认 + * + * @param string $prompt 提示信息 + * @param bool $default 默认值 + * @return bool 用户是否确认 + */ + protected function confirm(string $prompt, bool $default = true): bool + { + $helper = $this->getHelper('question'); + $question = new ConfirmationQuestion($prompt, $default); + return $helper->ask($this->input, $this->output, $question); + } + + /** + * 询问用户是否确认,否则退出 + * + * @param string $prompt 提示信息 + * @param bool $default 默认值 + */ + protected function confirmOrExit(string $prompt, bool $default = true): void + { + if (!$this->confirm($prompt, $default)) { + exit(self::SUCCESS); + } + } +}