Files
zhamao-framework/src/ZM/Command/Command.php

173 lines
5.0 KiB
PHP
Raw Normal View History

2022-12-16 17:59:32 +08:00
<?php
declare(strict_types=1);
namespace ZM\Command;
2022-12-31 22:59:03 +08:00
use Symfony\Component\Console\Helper\ProgressBar;
2022-12-16 17:59:32 +08:00
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
2022-12-17 16:27:49 +08:00
use Symfony\Component\Console\Output\ConsoleSectionOutput;
2022-12-16 17:59:32 +08:00
use Symfony\Component\Console\Output\OutputInterface;
use ZM\Exception\ZMException;
abstract class Command extends \Symfony\Component\Console\Command\Command
{
2022-12-17 16:27:49 +08:00
/**
* 输入
*/
2022-12-16 17:59:32 +08:00
protected InputInterface $input;
2022-12-17 16:27:49 +08:00
/**
* 输出
*
* 一般来说同样会是 ConsoleOutputInterface
*/
2022-12-16 17:59:32 +08:00
protected OutputInterface $output;
2022-12-17 16:27:49 +08:00
/**
* {@inheritdoc}
* @internal 不建议覆写此方法,建议使用 {@see handle()} 方法
*/
2022-12-16 17:59:32 +08:00
protected function execute(InputInterface $input, OutputInterface $output): int
{
$this->input = $input;
$this->output = $output;
2022-12-17 22:18:50 +08:00
if ($this->shouldExecute()) {
2022-12-25 23:11:10 +08:00
if (property_exists($this, 'bootstrappers')) {
foreach ($this->bootstrappers as $bootstrapper) {
(new $bootstrapper())->bootstrap($this->input->getOptions());
}
}
2022-12-17 22:18:50 +08:00
return $this->handle();
}
return self::SUCCESS;
}
/**
* 是否应该执行
*
* @return bool 返回 true 以继续执行,返回 false 以中断执行
*/
protected function shouldExecute(): bool
{
return true;
2022-12-16 17:59:32 +08:00
}
2022-12-17 16:27:49 +08:00
/**
* 命令的主体
*
* @return int 命令执行结果 {@see self::SUCCESS} {@see self::FAILURE} {@see self::INVALID}
*/
2022-12-16 17:59:32 +08:00
abstract protected function handle(): int;
2022-12-17 16:27:49 +08:00
/**
* 输出一段文本,默认样式
*
* @param string $message 要输出的文本
* @param bool $newline 是否在文本后换行
* @see OutputInterface::write()
*/
2022-12-16 17:59:32 +08:00
protected function write(string $message, bool $newline = true): void
{
$this->output->write($message, $newline);
}
2022-12-17 16:27:49 +08:00
/**
* 输出文本,一般用于提示信息
*
* @param string $message 要输出的文本
* @param bool $newline 是否在文本后换行
*/
2022-12-16 17:59:32 +08:00
protected function info(string $message, bool $newline = true): void
{
$this->write("<info>{$message}</info>", $newline);
}
2022-12-17 16:27:49 +08:00
/**
* 输出文本,一般用于错误信息
*
* @param string $message 要输出的文本
* @param bool $newline 是否在文本后换行
*/
2022-12-16 17:59:32 +08:00
protected function error(string $message, bool $newline = true): void
{
$this->write("<error>{$message}</error>", $newline);
}
2022-12-17 16:27:49 +08:00
/**
* 输出文本,一般用于警告或附注信息
*
* @param string $message 要输出的文本
* @param bool $newline 是否在文本后换行
*/
2022-12-16 17:59:32 +08:00
protected function comment(string $message, bool $newline = true): void
{
$this->write("<comment>{$message}</comment>", $newline);
}
2022-12-17 16:27:49 +08:00
/**
* 输出文本,一般用于提问信息
*
* @param string $message 要输出的文本
* @param bool $newline 是否在文本后换行
*/
2022-12-16 17:59:32 +08:00
protected function question(string $message, bool $newline = true): void
{
$this->write("<question>{$message}</question>", $newline);
}
2022-12-17 16:27:49 +08:00
/**
* 输出文本,一般用于详细信息
*
* @param string $message 要输出的文本
* @param bool $newline 是否在文本后换行
*/
2022-12-16 17:59:32 +08:00
protected function detail(string $message, bool $newline = true): void
{
$this->write("<fg=gray>{$message}</>", $newline);
}
2022-12-17 16:27:49 +08:00
/**
* 输出一个区块,区块内内容可以覆写
*
* 此功能需要 $output {@see ConsoleOutputInterface} 类型
*
* @param string $message 作为标题的文本
* @param callable $callback 回调函数,接收一个参数,类型为 {@see ConsoleSectionOutput}
*/
2022-12-16 17:59:32 +08:00
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());
2022-12-17 16:27:49 +08:00
exit(self::FAILURE);
2022-12-16 17:59:32 +08:00
}
}
2022-12-31 22:59:03 +08:00
/**
* 获取一个进度条实例
*
* @param int $max 最大进度值,可以稍后再设置
*/
protected function progress(int $max = 0): ProgressBar
{
$progress = new ProgressBar($this->output, $max);
$progress->setBarCharacter('<fg=green>⚬</>');
$progress->setEmptyBarCharacter('<fg=red>⚬</>');
$progress->setProgressCharacter('<fg=green>➤</>');
$progress->setFormat(
2022-12-31 23:57:56 +08:00
"%current%/%max% [%bar%] %percent:3s%%\n🪅 %estimated:-20s% %memory:20s%" . PHP_EOL
2022-12-31 22:59:03 +08:00
);
return $progress;
}
2022-12-16 17:59:32 +08:00
}