2020-08-31 10:11:06 +08:00
|
|
|
<?php
|
|
|
|
|
|
2022-03-15 18:05:33 +08:00
|
|
|
declare(strict_types=1);
|
2020-08-31 10:11:06 +08:00
|
|
|
|
|
|
|
|
namespace ZM;
|
|
|
|
|
|
2022-03-15 18:05:33 +08:00
|
|
|
use Symfony\Component\Console\Application;
|
2022-12-17 22:18:50 +08:00
|
|
|
use Symfony\Component\Console\Attribute\AsCommand;
|
|
|
|
|
use Symfony\Component\Console\CommandLoader\FactoryCommandLoader;
|
2022-03-15 18:05:33 +08:00
|
|
|
use Symfony\Component\Console\Input\InputInterface;
|
|
|
|
|
use Symfony\Component\Console\Output\OutputInterface;
|
2022-12-16 17:58:52 +08:00
|
|
|
use ZM\Exception\SingletonViolationException;
|
2022-12-17 22:18:50 +08:00
|
|
|
use ZM\Store\FileSystem;
|
2020-08-31 10:11:06 +08:00
|
|
|
|
2022-08-01 16:31:54 +08:00
|
|
|
/**
|
|
|
|
|
* 命令行启动的入口文件,用于初始化环境变量,并启动命令行应用
|
|
|
|
|
*
|
|
|
|
|
* 这里启动的不是框架,而是框架相关的命令行环境
|
|
|
|
|
*/
|
2022-08-13 17:00:29 +08:00
|
|
|
final class ConsoleApplication extends Application
|
2020-08-31 10:11:06 +08:00
|
|
|
{
|
2022-03-15 18:05:33 +08:00
|
|
|
private static $obj;
|
2021-07-04 15:45:30 +08:00
|
|
|
|
2022-08-01 16:31:54 +08:00
|
|
|
public function __construct(string $name = 'zhamao-framework')
|
2022-03-15 18:05:33 +08:00
|
|
|
{
|
|
|
|
|
if (self::$obj !== null) {
|
2022-12-16 17:58:52 +08:00
|
|
|
throw new SingletonViolationException(self::class);
|
2022-03-15 18:05:33 +08:00
|
|
|
}
|
2022-03-13 22:50:01 +08:00
|
|
|
|
2022-08-01 16:31:54 +08:00
|
|
|
// 初始化命令
|
2022-12-17 22:18:50 +08:00
|
|
|
$command_classes = FileSystem::getClassesPsr4(zm_dir('src/ZM/Command'), 'ZM\\Command');
|
|
|
|
|
$commands = [];
|
|
|
|
|
foreach ($command_classes as $command_class) {
|
|
|
|
|
try {
|
|
|
|
|
$command_class_ref = new \ReflectionClass($command_class);
|
|
|
|
|
} catch (\ReflectionException $e) {
|
|
|
|
|
logger()->error("命令 {$command_class} 无法加载!反射失败:" . $e->getMessage());
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if ($command_class_ref->isAbstract()) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
// 从 AsCommand 注解中获取命令名称
|
|
|
|
|
$attr = $command_class_ref->getAttributes(AsCommand::class);
|
|
|
|
|
if (count($attr) > 0) {
|
|
|
|
|
$commands[$attr[0]->getArguments()['name']] = fn () => new $command_class();
|
|
|
|
|
} else {
|
|
|
|
|
logger()->warning("命令 {$command_class} 没有使用 AsCommand 注解,无法被加载");
|
|
|
|
|
}
|
2021-06-16 00:17:30 +08:00
|
|
|
}
|
2022-12-17 22:18:50 +08:00
|
|
|
// 命令工厂,用于延迟加载命令
|
|
|
|
|
$command_loader = new FactoryCommandLoader($commands);
|
|
|
|
|
$this->setCommandLoader($command_loader);
|
2022-08-01 16:31:54 +08:00
|
|
|
|
|
|
|
|
self::$obj = $this; // 用于标记已经初始化完成
|
|
|
|
|
parent::__construct($name, ZM_VERSION);
|
2020-08-31 10:11:06 +08:00
|
|
|
}
|
|
|
|
|
|
2022-08-01 16:31:54 +08:00
|
|
|
/**
|
|
|
|
|
* {@inheritdoc}
|
|
|
|
|
*/
|
2022-03-15 18:05:33 +08:00
|
|
|
public function run(InputInterface $input = null, OutputInterface $output = null): int
|
|
|
|
|
{
|
2020-08-31 10:11:06 +08:00
|
|
|
try {
|
|
|
|
|
return parent::run($input, $output);
|
2022-11-03 10:18:17 +08:00
|
|
|
} catch (\Exception $e) {
|
2022-03-15 18:05:33 +08:00
|
|
|
echo zm_internal_errcode('E00005') . "{$e->getMessage()} at {$e->getFile()}({$e->getLine()})" . PHP_EOL;
|
|
|
|
|
exit(1);
|
2020-08-31 10:11:06 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|