Skip to content

⚡ 便捷方法

一组高层封装,把「判断项目状态」「读 composer.json/lock」「列已装包/直接依赖」「按类型/废弃筛选」「命名空间/脚本查询」「目录定位」等常用操作收敛为一行调用。

这些方法大多直接读文件或组合多个 composer 子命令,避免你手写解析逻辑。它们分三类:🩺 状态判断、📊 项目摘要、🔍 目录与配置查询。

何时使用

  • 🩺 启动时快速判断当前目录是否 Composer 项目、是否已 install。
  • 📊 生成项目体检报告:依赖数、过时包数、漏洞数、Composer/PHP 版本——一条 GetProjectSummary 搞定。
  • 📋 列出已装包名或直接依赖名,用于依赖分析脚本。
  • 🎯 按类型筛包(找出所有 composer-plugin)或找出已废弃包。
  • 🗂️ 拿到 vendor/bin/cache/home 目录路径,规划缓存或产物。

结构化类型

ProjectSummary

GetProjectSummary 返回,聚合多源信息的项目体检报告。

go
type ProjectSummary struct {
    Name                  string `json:"name,omitempty"`
    Description           string `json:"description,omitempty"`
    Type                  string `json:"type,omitempty"`
    License               string `json:"license,omitempty"`
    DirectDependencyCount int    `json:"direct_dependency_count"`
    DevDependencyCount    int    `json:"dev_dependency_count"`
    TotalInstalledCount   int    `json:"total_installed_count"`
    OutdatedCount         int    `json:"outdated_count"`
    VulnerabilityCount    int    `json:"vulnerability_count"`
    ComposerVersion       string `json:"composer_version,omitempty"`
    PHPVersion            string `json:"php_version,omitempty"`
}

ProjectDependencies

GetProjectDependencies 返回,依赖计数与包名列表。

go
type ProjectDependencies struct {
    DirectCount       int      `json:"direct_count"`
    DevCount          int      `json:"dev_count"`
    TotalInstalled    int      `json:"total_installed"`
    DirectPackages    []string `json:"direct_packages,omitempty"`
    DevPackages       []string `json:"dev_packages,omitempty"`
    InstalledPackages []string `json:"installed_packages,omitempty"`
}

方法签名

🩺 状态判断

方法签名说明
📦 IsProjectfunc (c *Composer) IsProject() bool当前工作目录是否有 composer.json
📂 IsProjectInfunc (c *Composer) IsProjectIn(dir string) bool指定目录是否有 composer.json
🔒 HasComposerLockfunc (c *Composer) HasComposerLock() bool是否存在 composer.lock
📁 HasVendorDirfunc (c *Composer) HasVendorDir() bool是否存在 vendor 目录
✅ IsPackageInstalledfunc (c *Composer) IsPackageInstalled(packageName string) bool包是否已安装
🧪 IsPackageDevfunc (c *Composer) IsPackageDev(packageName string) (bool, error)包是否在 require-dev

📊 项目摘要与依赖

方法签名说明
📋 GetInstalledPackageNamesfunc (c *Composer) GetInstalledPackageNames() ([]string, error)所有已装包名
🎯 GetDirectDependencyNamesfunc (c *Composer) GetDirectDependencyNames() ([]string, error)直接依赖包名
🔢 GetPackageVersionsListfunc (c *Composer) GetPackageVersionsList(packageName string) ([]string, error)某包所有可用版本
📊 GetProjectDependenciesfunc (c *Composer) GetProjectDependencies() (*ProjectDependencies, error)依赖摘要
📈 GetProjectSummaryfunc (c *Composer) GetProjectSummary() (*ProjectSummary, error)项目体检报告
🔖 GetRequireWithVersionfunc (c *Composer) GetRequireWithVersion(packageName string) (string, error)包的已装版本号
🏷️ GetPackagesByTypefunc (c *Composer) GetPackagesByType(packageType string) ([]string, error)按类型筛包
⚠️ GetAbandonedPackagesFromLockfunc (c *Composer) GetAbandonedPackagesFromLock() ([]string, error)从 lock 找废弃包
🗺️ GetNamespaceMapfunc (c *Composer) GetNamespaceMap() (map[string]string, error)PSR-4 命名空间→目录映射
📜 GetScriptsfunc (c *Composer) GetScripts() (map[string]interface{}, error)composer.json 脚本

🗂️ 目录与文件读取

方法签名说明
🏠 GetComposerHomeDirfunc (c *Composer) GetComposerHomeDir() (string, error)composer config home
💾 GetCacheDirfunc (c *Composer) GetCacheDir() (string, error)composer config cache-dir
📦 GetVendorDirfunc (c *Composer) GetVendorDir() (string, error)vendor 目录(带回退默认值)
🗂️ GetBinDirfunc (c *Composer) GetBinDir() (string, error)bin 目录(带回退默认值)

🔧 包级解析函数

方法签名说明
📋 ParsePackageListfunc ParsePackageList(output string) []string解析 composer show 文本输出
🔢 ParsePackageVersionsfunc ParsePackageVersions(output string) ([]string, error)解析 show --all --format=json 版本

示例

项目体检报告

go
package main

import (
	"fmt"
	"log"

	"github.com/scagogogo/composer-skills/pkg/composer"
)

func main() {
	comp, err := composer.New(composer.DefaultOptions())
	if err != nil {
		log.Fatal(err)
	}

	summary, err := comp.GetProjectSummary()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("📦 %s (%s)\n", summary.Name, summary.Type)
	fmt.Printf("   直接依赖 %d / 开发依赖 %d / 已安装 %d\n",
		summary.DirectDependencyCount, summary.DevDependencyCount, summary.TotalInstalledCount)
	fmt.Printf("   过时 %d / 漏洞 %d\n", summary.OutdatedCount, summary.VulnerabilityCount)
	fmt.Printf("   Composer %s / PHP %s\n", summary.ComposerVersion, summary.PHPVersion)
}

列出所有已装包名

go
pkgs, err := comp.GetInstalledPackageNames()
if err != nil {
	log.Fatal(err)
}
for _, p := range pkgs {
	fmt.Println(p)
}

按类型筛包

go
plugins, err := comp.GetPackagesByType("composer-plugin")
if err != nil {
	log.Fatal(err)
}
for _, p := range plugins {
	fmt.Println("🔌", p)
}

找出已废弃包

go
abandoned, err := comp.GetAbandonedPackagesFromLock()
if err != nil {
	log.Fatal(err)
}
if len(abandoned) > 0 {
	fmt.Println("⚠️ 以下包已废弃,建议替换:")
	for _, p := range abandoned {
		fmt.Println("  -", p)
	}
}

查某包已装版本

go
v, err := comp.GetRequireWithVersion("symfony/console")
if err != nil {
	log.Fatal(err)
}
fmt.Println("symfony/console 版本:", v)

判断项目状态

go
if !comp.IsProject() {
	log.Fatal("当前目录不是 Composer 项目")
}
if !comp.HasComposerLock() {
	fmt.Println("⚠️ 缺少 composer.lock,建议执行 composer install")
}
if !comp.HasVendorDir() {
	fmt.Println("⚠️ 缺少 vendor 目录,依赖未安装")
}
if comp.IsPackageInstalled("phpunit/phpunit") {
	fmt.Println("✅ 已安装 PHPUnit")
}

拿目录路径

go
home, _ := comp.GetComposerHomeDir()
cache, _ := comp.GetCacheDir()
vendor, _ := comp.GetVendorDir()
bin, _ := comp.GetBinDir()
fmt.Printf("home=%s\ncache=%s\nvendor=%s\nbin=%s\n", home, cache, vendor, bin)

解析函数独立使用

go
// 你可以自己跑 composer show 拿输出,再用 ParsePackageList 提取
output := `symfony/console    v5.4.0  Eases...
monolog/monolog    2.5.0   Sends...`
for _, name := range composer.ParsePackageList(output) {
	fmt.Println(name)
}

进阶

GetProjectSummary 的容错

GetProjectSummary 内部对每个子调用都做了 err == nil 判断——任何一项失败(如无 lock 文件)只会让对应字段留空,不会中断整体报告。这让它适合做「尽力而为」的体检。

两个废弃包方法

GetAbandonedPackagesFromLock(本文件)直接读 composer.lockabandoned 字段,无需执行命令;audit.goGetAbandonedPackagescomposer audit 命令并返回 []Vulnerability。前者快、后者全(含废弃原因等额外信息)。

GetVendorDir / GetBinDir 的回退

composer config vendor-dir 失败(如未初始化项目),它们回退到 <工作目录>/vendor<工作目录>/vendor/bin,不返回错误。这是有意设计,便于在项目未配置时也能拿到合理默认路径。

IsPackageInstalled 的判定

IsPackageInstalled 执行 composer show <pkg>,成功即视为已安装。注意 Composer 在包存在但版本异常时也可能返回非零退出码,此判定是「乐观」的。

基于 MIT 许可证发布