Skip to content

Doctor 模块

Doctor 模块是一个较为独立的用于检查系统环境的模块,可使用命令 bin/spc doctor 进入,入口的命令类在 DoctorCommand.php 中。

Doctor 模块是一个检查单,里面有一系列的检查项目和自动修复项目。这些项目都存放在 src/SPC/doctor/item/ 目录中, 并且使用了两种 Attribute 用作检查项标记和自动修复项目标记:#[AsCheckItem]#[AsFixItem]

以现有的检查项 if necessary tools are installed,它是用于检查编译必需的包是否安装在 macOS 系统内,下面是它的源码:

php
use SPC\doctor\AsCheckItem;
use SPC\doctor\AsFixItem;
use SPC\doctor\CheckResult;

#[AsCheckItem('if necessary tools are installed', limit_os: 'Darwin', level: 997)]
public function checkCliTools(): ?CheckResult
{
    $missing = [];
    foreach (self::REQUIRED_COMMANDS as $cmd) {
        if ($this->findCommand($cmd) === null) {
            $missing[] = $cmd;
        }
    }
    if (!empty($missing)) {
        return CheckResult::fail('missing system commands: ' . implode(', ', $missing), 'build-tools', [$missing]);
    }
    return CheckResult::ok();
}

属性的第一个参数就是检查项目的名称,后面的 limit_os 参数是限制了该检查项仅在指定的系统下触发,level 是执行该检查项的优先级,数字越大,优先级越高。

里面用到的 $this->findCommand() 方法为 SPC\builder\traits\UnixSystemUtilTrait 的方法,用途是查找系统命令所在位置,找不到时返回 NULL。

每个检查项的方法都应该返回一个 SPC\doctor\CheckResult

  • 在返回 CheckResult::fail() 时,第一个参数用于输出终端的错误提示,第二个参数是在这个检查项可自动修复时的修复项目名称。
  • 在返回 CheckResult::ok() 时,表明检查通过。你也可以传递一个参数,用于返回检查结果,例如:CheckResult::ok('OS supported')
  • 在返回 CheckResult::fail() 时,如果包含了第三个参数,第三个参数的数组将被当作 AsFixItem 的参数。

下面是这个检查项对应的自动修复项的方法:

php
#[AsFixItem('build-tools')]
public function fixBuildTools(array $missing): bool
{
    foreach ($missing as $cmd) {
        try {
            shell(true)->exec('brew install ' . escapeshellarg($cmd));
        } catch (RuntimeException) {
            return false;
        }
    }
    return true;
}

#[AsFixItem()] 属性传入的参数即修复项的名称,该方法必须返回 True 或 False。当返回 False 时,表明自动修复失败,需要手动处理。

此处的代码中 shell()->exec() 是项目的执行命令的方法,用于替代 exec()system(),同时提供了 debug、获取执行状态、进入目录等特性。

Released under the MIT License.