From b8524715966a1be1b0dfea8a7cd80fd6a8a5f81e Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 28 Jun 2023 18:38:14 +0800 Subject: [PATCH] add manual doctors --- src/SPC/doctor/AsCheckItem.php | 3 +- src/SPC/doctor/AsFixItem.php | 2 +- src/SPC/doctor/CheckListHandler.php | 53 ++++++++++++++++++----------- src/SPC/doctor/CheckResult.php | 12 +++---- src/SPC/doctor/item/OSCheckList.php | 4 +-- 5 files changed, 44 insertions(+), 30 deletions(-) diff --git a/src/SPC/doctor/AsCheckItem.php b/src/SPC/doctor/AsCheckItem.php index 6c20e38c..0417bcfa 100644 --- a/src/SPC/doctor/AsCheckItem.php +++ b/src/SPC/doctor/AsCheckItem.php @@ -12,7 +12,8 @@ class AsCheckItem public function __construct( public string $item_name, public ?string $limit_os = null, - public int $level = 100 + public int $level = 100, + public bool $manual = false, ) { } } diff --git a/src/SPC/doctor/AsFixItem.php b/src/SPC/doctor/AsFixItem.php index 92f5e35e..eb26d872 100644 --- a/src/SPC/doctor/AsFixItem.php +++ b/src/SPC/doctor/AsFixItem.php @@ -4,7 +4,7 @@ declare(strict_types=1); namespace SPC\doctor; -#[\Attribute(\Attribute::TARGET_METHOD)] +#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] class AsFixItem { public function __construct(public string $name) diff --git a/src/SPC/doctor/CheckListHandler.php b/src/SPC/doctor/CheckListHandler.php index b2f53e45..f627e632 100644 --- a/src/SPC/doctor/CheckListHandler.php +++ b/src/SPC/doctor/CheckListHandler.php @@ -24,9 +24,20 @@ class CheckListHandler * @throws FileSystemException * @throws RuntimeException */ - public function __construct(private InputInterface $input, private OutputInterface $output) + public function __construct(private InputInterface $input, private OutputInterface $output, bool $include_manual = false) { - $this->loadCheckList(); + $this->loadCheckList($include_manual); + } + + public function runSingleCheck(string $item_name, int $fix_policy = FIX_POLICY_DIE): void + { + foreach ($this->check_list as $item) { + if ($item->item_name === $item_name) { + $this->check_list = [$item]; + break; + } + } + $this->runCheck($fix_policy); } /** @@ -44,7 +55,7 @@ class CheckListHandler $this->output->writeln('skipped'); } elseif ($result instanceof CheckResult) { if ($result->isOK()) { - $this->output->writeln('ok'); + $this->output->writeln($result->getMessage() ?? 'ok'); continue; } // Failed @@ -85,28 +96,30 @@ class CheckListHandler * @throws RuntimeException * @throws FileSystemException */ - private function loadCheckList(): void + private function loadCheckList(bool $include_manual = false): void { foreach (FileSystem::getClassesPsr4(__DIR__ . '/item', 'SPC\\doctor\\item') as $class) { $ref = new \ReflectionClass($class); foreach ($ref->getMethods() as $method) { - $attr = $method->getAttributes(AsCheckItem::class); - if (isset($attr[0])) { - /** @var AsCheckItem $instance */ - $instance = $attr[0]->newInstance(); - $instance->callback = [new $class(), $method->getName()]; - $this->check_list[] = $instance; - continue; - } - $attr = $method->getAttributes(AsFixItem::class); - if (isset($attr[0])) { - /** @var AsFixItem $instance */ - $instance = $attr[0]->newInstance(); - // Redundant fix item - if (isset($this->fix_map[$instance->name])) { - throw new RuntimeException('Redundant doctor fix item: ' . $instance->name); + $attr = $method->getAttributes(); + foreach ($attr as $a) { + if (is_a($a->getName(), AsCheckItem::class, true)) { + /** @var AsCheckItem $instance */ + $instance = $a->newInstance(); + if (!$include_manual && $instance->manual) { + continue; + } + $instance->callback = [new $class(), $method->getName()]; + $this->check_list[] = $instance; + } elseif (is_a($a->getName(), AsFixItem::class, true)) { + /** @var AsFixItem $instance */ + $instance = $a->newInstance(); + // Redundant fix item + if (isset($this->fix_map[$instance->name])) { + throw new RuntimeException('Redundant doctor fix item: ' . $instance->name); + } + $this->fix_map[$instance->name] = [new $class(), $method->getName()]; } - $this->fix_map[$instance->name] = [new $class(), $method->getName()]; } } } diff --git a/src/SPC/doctor/CheckResult.php b/src/SPC/doctor/CheckResult.php index fef036e4..4a1394d4 100644 --- a/src/SPC/doctor/CheckResult.php +++ b/src/SPC/doctor/CheckResult.php @@ -6,21 +6,21 @@ namespace SPC\doctor; class CheckResult { - public function __construct(private string $message = '', private string $fix_item = '', private array $fix_params = []) + public function __construct(private bool $ok, private ?string $message = null, private string $fix_item = '', private array $fix_params = []) { } public static function fail(string $message, string $fix_item = '', array $fix_params = []): CheckResult { - return new static($message, $fix_item, $fix_params); + return new static(false, $message, $fix_item, $fix_params); } - public static function ok(): CheckResult + public static function ok(?string $message = null): CheckResult { - return new static(); + return new static(true, $message); } - public function getMessage(): string + public function getMessage(): ?string { return $this->message; } @@ -37,7 +37,7 @@ class CheckResult public function isOK(): bool { - return empty($this->message); + return $this->ok; } public function setFixItem(string $fix_item = '', array $fix_params = []) diff --git a/src/SPC/doctor/item/OSCheckList.php b/src/SPC/doctor/item/OSCheckList.php index 1bab92cd..5d074793 100644 --- a/src/SPC/doctor/item/OSCheckList.php +++ b/src/SPC/doctor/item/OSCheckList.php @@ -12,12 +12,12 @@ class OSCheckList { use UnixSystemUtilTrait; - #[AsCheckItem('if current os are supported', level: 999)] + #[AsCheckItem('if current OS are supported', level: 999)] public function checkOS(): ?CheckResult { if (!in_array(PHP_OS_FAMILY, ['Darwin', 'Linux'])) { return CheckResult::fail('Current OS is not supported'); } - return CheckResult::ok(); + return CheckResult::ok(PHP_OS_FAMILY . ' ' . php_uname('m') . ', supported'); } }