Skip to content

🩺 诊断与健康检查

诊断系统环境、检查依赖本地修改与同步性,并执行覆盖环境/配置/依赖/安全的综合健康检查。

Composer 自带一组「自检」命令:status 查看已安装包是否有本地修改、diagnose 排查常见环境错误、check 校验 composer.jsoncomposer.lock 的一致性、exec 执行本地包二进制。Composer Skills 在此之上提供两层封装:返回原始文本的基础方法,以及返回结构化结果的 *Structured 方法与解析函数。最顶层的 HealthCheck 把环境、配置、依赖、安全等多维度检查汇聚成一个 HealthStatus

何时使用

  • 🩺 新机器接入:跑一次 Diagnose 排查 Composer 环境常见问题(HTTP 代理、证书、磁盘空间等)。
  • 📦 提交前检查:Status 确认没有遗留的本地修改污染依赖目录。
  • 🔄 CI 同步性校验:CheckStructured 判断 composer.jsoncomposer.lock 是否同步。
  • 🚀 发布前总览:HealthCheck 一次调用拿到「healthy / warning / critical」总评与问题清单。
  • ⚙️ 运行本地工具:LocalExec 调用 vendor/bin/ 下的二进制(如 phpunit、phpstan)。

结构化返回类型

StatusResult

StatusStructured / ParseStatusOutput 返回,对应 composer status

go
type StatusResult struct {
    Modified bool     `json:"modified"`
    Files    []string `json:"files,omitempty"`
    Output   string   `json:"output,omitempty"`
}
字段类型说明
Modifiedbool是否存在本地修改的文件
Files[]string被修改的文件列表
Outputstring原始输出

CheckResult

CheckStructured / ParseCheckOutput 返回,对应 composer check

go
type CheckResult struct {
    Valid     bool     `json:"valid"`
    Messages  []string `json:"messages,omitempty"`
    Warnings  []string `json:"warnings,omitempty"`
    Errors    []string `json:"errors,omitempty"`
}
字段类型说明
Validboolcomposer.jsoncomposer.lock 是否同步/有效
Messages[]string普通信息
Warnings[]string警告信息
Errors[]string错误信息(出现则 Valid=false

DiagnoseResult / DiagnoseCheck

DiagnoseStructured / ParseDiagnoseOutput 返回,对应 composer diagnose

go
type DiagnoseCheck struct {
    Name   string `json:"name"`
    Status string `json:"status"` // "ok", "warning", "error", "info"
    Detail string `json:"detail,omitempty"`
}

type DiagnoseResult struct {
    Checks []DiagnoseCheck `json:"checks,omitempty"`
}
字段类型说明
Namestring检查项名称
Statusstring状态:ok/warning/error/info
Detailstring原始行内容
Checks[]DiagnoseCheck全部检查项

状态判定

ParseDiagnoseOutput 按行扫描,依据前缀判定状态:[OK]ok[WARNING]warning[ERROR]error;其余归为 info

BatchRequireResult / BatchRemoveResult

批量添加/移除包的结果。

go
type BatchRequireResult struct {
    Results      []RequireResult `json:"results,omitempty"`
    SuccessCount int             `json:"success_count"`
    FailCount    int             `json:"fail_count"`
    TotalCount   int             `json:"total_count"`
}

type BatchRemoveResult struct {
    Results      []RemoveResult `json:"results,omitempty"`
    SuccessCount int            `json:"success_count"`
    FailCount    int            `json:"fail_count"`
    TotalCount   int            `json:"total_count"`
}
字段类型说明
Results[]RequireResult/[]RemoveResult各包的逐项结果
SuccessCountint成功数量
FailCountint失败数量
TotalCountint总数量

HealthStatus

HealthCheck 返回的综合健康状态。

go
type HealthStatus struct {
    ComposerInstalled   bool     `json:"composer_installed"`
    ComposerVersion     string   `json:"composer_version,omitempty"`
    PHPAvailable        bool     `json:"php_available"`
    PHPVersion          string   `json:"php_version,omitempty"`
    HasComposerJson     bool     `json:"has_composer_json"`
    HasComposerLock     bool     `json:"has_composer_lock"`
    HasVendorDir        bool     `json:"has_vendor_dir"`
    Valid               bool     `json:"valid,omitempty"`
    OutdatedCount       int      `json:"outdated_count,omitempty"`
    VulnerabilityCount  int      `json:"vulnerability_count,omitempty"`
    AbandonedCount      int      `json:"abandoned_count,omitempty"`
    OverallStatus       string   `json:"overall_status"`
    Issues              []string `json:"issues,omitempty"`
}
字段类型说明
ComposerInstalledboolComposer 是否已安装
ComposerVersionstringComposer 版本号
PHPAvailableboolPHP 是否可用
PHPVersionstringPHP 版本号
HasComposerJsonbool是否存在 composer.json
HasComposerLockbool是否存在 composer.lock
HasVendorDirbool是否存在 vendor 目录
Validboolcomposer.json 是否通过验证
OutdatedCountint过时包数量
VulnerabilityCountint安全漏洞数量
AbandonedCountint已放弃包数量
OverallStatusstring总体状态:healthy / warning / critical
Issues[]string发现的问题清单

OverallStatus 判定规则

  • critical:Composer/PHP 未安装、缺少 composer.jsoncomposer.json 验证失败、发现安全漏洞。
  • warning:缺少 composer.lock、缺少 vendor 目录、存在过时包、存在已放弃包(在非 critical 情况下升级为 warning)。
  • healthy:所有检查均通过。

Status

🩺 显示已安装包的本地修改。

签名

go
func (c *Composer) Status() (string, error)

参数

无。

返回值

类型说明
输出stringcomposer status 的输出
错误error执行失败时返回

等价命令

composer status

示例

go
output, err := comp.Status()
if err != nil {
    log.Fatalf("检查状态失败: %v", err)
}
if output != "" {
    fmt.Println("发现本地修改:")
    fmt.Println(output)
} else {
    fmt.Println("无本地修改")
}

进阶:StatusWithOptions

go
func (c *Composer) StatusWithOptions(options map[string]string) (string, error)

附加自定义选项,等价 composer status <flags>

go
output, err := comp.StatusWithOptions(map[string]string{"verbose": ""})

Diagnose

🩺 诊断系统以识别常见错误。

签名

go
func (c *Composer) Diagnose() (string, error)

参数

无。

返回值

类型说明
输出stringcomposer diagnose 的输出
错误error执行失败时返回

等价命令

composer diagnose

示例

go
output, err := comp.Diagnose()
if err != nil {
    log.Fatalf("诊断失败: %v", err)
}
fmt.Println("诊断结果:")
fmt.Println(output)

进阶:DiagnoseWithOptions

go
func (c *Composer) DiagnoseWithOptions(options map[string]string) (string, error)

附加自定义选项。


Check

🩺 检查依赖项是否满足要求(composer.jsoncomposer.lock 同步性)。

签名

go
func (c *Composer) Check() (string, error)

参数

无。

返回值

类型说明
输出stringcomposer check 的输出
错误error执行失败时返回

等价命令

composer check

示例

go
output, err := comp.Check()
if err != nil {
    log.Fatalf("检查失败: %v", err)
}
fmt.Println("检查结果:", output)

进阶:CheckWithOptions

go
func (c *Composer) CheckWithOptions(options map[string]string) (string, error)

附加自定义选项。


LocalExec

🩺 执行本地包中的二进制文件(vendor/bin/ 下的命令)。

签名

go
func (c *Composer) LocalExec(command string, args ...string) (string, error)

参数

参数类型说明
commandstring要执行的本地二进制名称,如 phpunit
args...string透传给该二进制的参数

返回值

类型说明
输出string二进制执行的标准输出
错误error执行失败时返回

等价命令

composer exec <command> [args...]

示例

go
// 运行 phpunit
output, err := comp.LocalExec("phpunit", "--testsuite=unit")
if err != nil {
    log.Fatalf("执行失败: %v", err)
}
fmt.Println(output)

进阶:LocalExecWithOptions

go
func (c *Composer) LocalExecWithOptions(command string, options map[string]string, args ...string) (string, error)

在命令与参数之间插入自定义选项(如 ----dev 等)。

go
output, err := comp.LocalExecWithOptions(
    "phpstan",
    map[string]string{"verbose": ""},
    "analyse", "src",
)

Structured 变体

StatusStructured

🩺 检查依赖是否有本地修改,返回结构化结果。

go
func (c *Composer) StatusStructured() (*StatusResult, error)
类型说明
结果*StatusResultModifiedFiles
错误error执行失败时返回
go
result, err := comp.StatusStructured()
if err != nil {
    log.Fatalf("检查状态失败: %v", err)
}
if result.Modified {
    fmt.Printf("发现 %d 个修改的文件\n", len(result.Files))
    for _, f := range result.Files {
        fmt.Println("- " + f)
    }
}

ParseStatusOutput

纯函数,把任意 composer status 文本输出解析为 *StatusResult

go
func ParseStatusOutput(output string) *StatusResult

解析逻辑:输出为空(含首尾空白)则 Modified=false;否则每一非空行视为一个被修改文件,置 Modified=true

CheckStructured

🩺 检查 composer.jsoncomposer.lock 是否同步,返回结构化结果。

go
func (c *Composer) CheckStructured() (*CheckResult, error)
类型说明
结果*CheckResultValid/Messages/Warnings/Errors
错误error执行错误(注意:命令返回非零退出码时 Validfalse,但不一定返回 error)

实现细节

CheckStructured 先执行 composer check,无论是否出错都用 ParseCheckOutput 解析输出;若命令报错,则额外把 Valid 置为 false。即「报错一定不通过」,但「不通过不一定有 Go 层 error」。

ParseCheckOutput

纯函数,把任意 composer check 文本输出解析为 *CheckResult

go
func ParseCheckOutput(output string) *CheckResult

解析逻辑:逐行扫描,含 error/Error/FAIL 的行归入 Errors 并置 Valid=false;含 warning/Warning/WARN 的行归入 Warnings;其余归入 Messages


ParseStatusOutput / ParseDiagnoseOutput

🩺 纯解析函数,便于对缓存或日志中的旧输出做事后分析,无需重新执行命令。

ParseDiagnoseOutput

go
func ParseDiagnoseOutput(output string) *DiagnoseResult
参数类型说明
outputstringcomposer diagnose 的原始输出

返回 *DiagnoseResult,逐行按前缀([OK]/[WARNING]/[ERROR]/)判定每项 Status

ParseDiagnoseOutputAsChecks

定义在 parsing.go,把 diagnose 输出解析为 []DiagnoseCheck 切片形式。

go
func ParseDiagnoseOutputAsChecks(output string) []DiagnoseCheck

DiagnoseStructured

🩺 执行诊断并返回结构化结果。

go
func (c *Composer) DiagnoseStructured() (*DiagnoseResult, error)
类型说明
结果*DiagnoseResultChecks 列表
错误error执行错误(注意:诊断发现问题不一定返回 error,需遍历 Checks 看状态)

返回值语义

DiagnoseStructured 把命令的 error 原样返回,但同时把输出解析为 DiagnoseResult。因此即使 err != nilresult 仍可能非空且含有效检查项。建议先看 result.Checks 再决定如何处理 err

go
result, err := comp.DiagnoseStructured()
if result != nil {
    for _, chk := range result.Checks {
        switch chk.Status {
        case "error":
            fmt.Printf("❌ %s\n", chk.Name)
        case "warning":
            fmt.Printf("⚠️  %s\n", chk.Name)
        case "ok":
            fmt.Printf("✅ %s\n", chk.Name)
        }
    }
}
if err != nil {
    log.Printf("诊断执行返回错误: %v", err)
}

BatchRequire / BatchRemove

🩺 批量添加/移除多个包,汇总成功与失败计数。

BatchRequire

go
func (c *Composer) BatchRequire(packages map[string]string, dev bool, continueOnError bool) (*BatchRequireResult, error)
参数类型说明
packagesmap[string]string包名 → 版本约束的映射
devbool是否作为开发依赖
continueOnErrorbool遇到错误是否继续;false 则遇到第一个错误即停止
返回值类型说明
结果*BatchRequireResult含逐项结果与成功/失败计数
错误errorcontinueOnError=false 时返回第一个遇到的错误
go
packages := map[string]string{
    "symfony/console": "^5.4",
    "monolog/monolog": "^2.0",
    "psr/log":         "^1.1",
}
result, err := comp.BatchRequire(packages, false, true)
if err != nil {
    log.Fatalf("批量添加失败: %v", err)
}
fmt.Printf("成功: %d, 失败: %d\n", result.SuccessCount, result.FailCount)

BatchRemove

go
func (c *Composer) BatchRemove(packages []string, dev bool, continueOnError bool) (*BatchRemoveResult, error)
参数类型说明
packages[]string要移除的包名列表
devbool是否从开发依赖中移除
continueOnErrorbool遇到错误是否继续
返回值类型说明
结果*BatchRemoveResult含逐项结果与成功/失败计数
错误errorcontinueOnError=false 时返回第一个遇到的错误

失败处理

两个批量方法在失败时会把错误信息追加到对应项的 Warnings 字段,便于事后排查。continueOnError=true 适合「尽量多装、最后汇总报告」的场景;false 适合「全部成功才算成功」的严格场景。


HealthCheck

🩺 执行全面的项目健康检查,汇聚环境、配置、依赖、安全多维度结果为单一 HealthStatus

签名

go
func (c *Composer) HealthCheck() (*HealthStatus, error)

参数

无。

返回值

类型说明
健康状态*HealthStatus含各项检查结果与总体状态
错误error错误信息

检查维度

依次执行以下检查(任一失败不影响后续检查):

  1. 🛠️ Composer 安装c.IsInstalled(),失败 → critical;成功则记录 ComposerVersion
  2. 💻 PHP 可用性installer.HasPHP(),失败 → critical;成功则记录 PHPVersion
  3. 📄 项目文件composer.json/composer.lock/vendor 目录是否存在,缺失分别升级到 critical 或 warning。
  4. 配置有效性c.ValidateStructured(),失败 → critical,并把逐条错误加入 Issues
  5. 📦 过时包c.GetOutdatedInfo(),数量 > 0 → warning。
  6. 🔒 安全漏洞c.GetAuditInfo(),数量 > 0 → critical。
  7. 🗑️ 已放弃包c.GetAbandonedPackagesFromLock(),数量 > 0 → warning。

示例

go
health, err := comp.HealthCheck()
if err != nil {
    log.Fatalf("健康检查失败: %v", err)
}
fmt.Printf("总体状态: %s\n", health.OverallStatus)
fmt.Printf("Composer: %s (installed=%v)\n", health.ComposerVersion, health.ComposerInstalled)
fmt.Printf("PHP: %s (available=%v)\n", health.PHPVersion, health.PHPAvailable)
fmt.Printf("过时包: %d, 漏洞: %d, 已放弃: %d\n",
    health.OutdatedCount, health.VulnerabilityCount, health.AbandonedCount)
if len(health.Issues) > 0 {
    fmt.Println("问题清单:")
    for _, issue := range health.Issues {
        fmt.Printf("- %s\n", issue)
    }
}

进阶:GetHealthAsJSON

HealthCheck 结果序列化为缩进 JSON 字符串,便于嵌入 API 响应或写入报告文件。

go
func (c *Composer) GetHealthAsJSON() (string, error)
go
jsonStr, err := comp.GetHealthAsJSON()
if err != nil {
    log.Fatalf("序列化失败: %v", err)
}
fmt.Println(jsonStr)

进阶:GetInfoAsJSON

综合获取项目摘要信息并格式化为 JSON(基于 GetProjectSummary)。

go
func (c *Composer) GetInfoAsJSON() (string, error)

🔍 相关方法

  • 安全审计HealthCheck 内部调用 GetAuditInfoGetAbandonedPackagesFromLock
  • 验证HealthCheck 内部调用 ValidateStructured 判断 composer.json 有效性。
  • 包管理BatchRequire/BatchRemove 内部调用 RequirePackage/Remove

基于 MIT 许可证发布