🚀 cli_advanced — 高级功能
本示例演示 Composer CLI 的高级能力:Satis 私有仓库构建、二进制命令执行、版本约束操作、环境诊断、项目归档,以及运行时环境变量调优。
🎯 示例定位
cli_advanced 是 Composer CLI 本地操作 系列的压轴示例(最后一个 CLI 示例)。它把前面示例未覆盖的进阶场景一次性收口,覆盖真实工程中才会碰到的边角能力。
- 📚 你将学到:用 SDK 驱动 Satis 私有仓库的初始化与构建;调用项目内二进制;读写版本约束;运行
diagnose/check/status体检;归档项目与单包;调整内存、超时、Vendor/Bin 目录等运行时环境。 - 🔗 对应 SDK 方法:
InitSatis/CreateSatisConfig/BuildSatis、Exec/ExecPHP/ExecWithList、LockPackageVersion/UpdatePackageVersion/FormatVersionConstraint、Diagnose/Check/Status/GetEnvironmentInfo/GetProjectInfo、Archive/ArchivePackage、SetMemoryLimit/SetProcessTimeout等包级环境函数。 - 💡 区别:
cli_basic_usage关注「跑通首条命令」、cli_package_management关注「增删改查包」。本例聚焦建设私有生态(Satis)、驱动工具链(Exec)、约束与体检(Version/Diagnosis)、产物分发(Archive)、运行时调参(Environment)五大主题。
💻 完整代码
📁 源文件:
examples/cli_advanced/01_satis_exec_version_diagnosis.go,按主题拆成 6 个示例函数,注释精简但逻辑完整。
go
package cli_advanced
import (
"fmt"
"log"
"github.com/scagogogo/composer-skills/pkg/composer"
)
// Example01Satis 演示 Satis 私有仓库的初始化、配置与构建
func Example01Satis() {
c, _ := composer.New(composer.DefaultOptions())
c.InitSatis("my-packages", "https://packages.example.com", "/path/to/satis")
c.CreateSatisConfig("/path/to/satis/satis.json", "my-packages", "https://packages.example.com")
c.AddSatisRepository("/path/to/satis/satis.json", "vcs", "https://github.com/myorg/myrepo")
c.AddSatisRequire("/path/to/satis/satis.json", "myorg/mypackage", "*")
output, _ := c.BuildSatis("/path/to/satis/satis.json", "/path/to/satis/web")
c.EnableSatisArchive("/path/to/satis/satis.json", "zip")
c.UpdateSatisStability("/path/to/satis/satis.json", "stable")
}
// Example02Exec 演示执行项目二进制与任意命令
func Example02Exec() {
c, _ := composer.New(composer.DefaultOptions())
c.SetWorkingDir("/path/to/project")
c.Exec("phpunit", "--version") // vendor/bin 下的二进制
c.ExecCommand("php", "-v") // 任意系统命令
c.ExecPHP("/usr/bin/php8.1", "phpunit", "--version") // 指定 PHP 解释器
binaries, _ := c.ExecWithList() // 列出可执行文件
c.ExecWithWorkingDir("phpunit", "/path/to/project", "--version")
}
// Example03VersionConstraints 演示版本约束的查询、锁定与格式化
func Example03VersionConstraints() {
c, _ := composer.New(composer.DefaultOptions())
c.SetWorkingDir("/path/to/project")
c.GetPackageVersions("symfony/console")
c.LockPackageVersion("symfony/console", "v6.0.0")
c.UpdatePackageVersion("symfony/console", "^6.0", composer.CaretVersion)
constraint := composer.FormatVersionConstraint("1.2.3", composer.CaretVersion) // ^1.2.3
constraint = composer.FormatVersionConstraint("1.2.3", composer.TildeVersion) // ~1.2.3
}
// Example04Diagnosis 演示诊断、检查与结构化信息获取
func Example04Diagnosis() {
c, _ := composer.New(composer.DefaultOptions())
c.SetWorkingDir("/path/to/project")
c.Diagnose() // composer diagnose 全面体检
c.Check() // 平台依赖校验
c.Status() // 工作区本地改动状态
envInfo, _ := c.GetEnvironmentInfo() // map[string]string
projectInfo, _ := c.GetProjectInfo() // 结构体,含 Name/Description
}
// Example05Archive 演示项目与单包归档
func Example05Archive() {
c, _ := composer.New(composer.DefaultOptions())
c.SetWorkingDir("/path/to/project")
c.Archive("./dist") // 整项目归档
c.ArchiveWithFormat("./dist", "zip") // 指定格式
c.ArchivePackage("symfony/console", "v6.0.0", "./dist") // 归档特定包版本
}
// Example06Environment 演示运行时环境调参(包级函数)
func Example06Environment() {
composer.SetMemoryLimit("2G") // COMPOSER_MEMORY_LIMIT
composer.SetProcessTimeout(600) // COMPOSER_PROCESS_TIMEOUT(秒)
composer.SetVendorDir("vendor-custom")
composer.SetBinDir("bin-custom")
path, _ := composer.GetComposerPath()
composer.DisableInteraction() // CI 中禁用 -n 交互
composer.EnableInteraction()
}🧩 代码讲解
🏗️ Satis 私有仓库(Example01Satis)
- 🏠
InitSatis创建 Satis 工作区骨架,是构建私有 Packagist 镜像的起点;CreateSatisConfig生成后续所有配置都基于的satis.json。 - 🔗
AddSatisRepository(path, "vcs", url)挂载 Git 源,AddSatisRequire(path, pkg, "*")声明收录哪些包;两者共同决定镜像内容。 - 🏭
BuildSatis(configPath, webDir)物化为静态 Web 目录;EnableSatisArchive(path, "zip")同时产出 zip;UpdateSatisStability(path, "stable")等价设minimum-stability。
⚙️ 命令执行(Example02Exec)
- 🛠️
Exec("phpunit", ...)等价composer exec,自动在vendor/bin查找;ExecCommand("php", "-v")跳过查找直接执行系统命令。 - 🐘
ExecPHP(phpPath, bin, args)用显式 PHP 路径驱动二进制,便于多版本切换;ExecWithList()返回可执行清单,适合工具链自检。 - 📂
ExecWithWorkingDir(bin, dir, args)临时切目录而不改实例状态,适合一次性调用。
🔢 版本约束(Example03VersionConstraints)
- 🔎
GetPackageVersions(pkg)输出可用版本,是决定约束策略的前提;LockPackageVersion固定到精确版本用于复现性构建。 - 📐
UpdatePackageVersion(pkg, "^6.0", CaretVersion)用语义约束符改require;FormatVersionConstraint是纯函数,把裸版本号拼成^1.2.3/~1.2.3,不碰文件系统。
🩺 诊断与体检(Example04Diagnosis)
- 🩻
Diagnose()全面体检(HTTP/Git/缓存/权限),Check()校验平台依赖,Status()看本地改动,三者均返回原始文本。 - 🧬
GetEnvironmentInfo()返回键值化环境信息,GetProjectInfo()返回结构体(直接取Name/Description),免正则解析。
📦 归档(Example05Archive)
- 🗜️
Archive("./dist")整项目打包;ArchiveWithFormat("./dist", "zip")显式选 zip/tar;ArchivePackage(pkg, ver, dir)归档任意包的指定版本,适合为离线镜像备料。
🌡️ 运行时环境(Example06Environment)
- 🧠
SetMemoryLimit("2G")解大依赖树 OOM;⏱️SetProcessTimeout(600)防慢网络下 Git 拉取被误杀。 - 📁
SetVendorDir/SetBinDir改默认安装目录,需与项目composer.json的config段一致;🛰️GetComposerPath()便于脚本复用同一份 Composer;🔇DisableInteraction对应-n,CI 中必开。
▶️ 运行方式
本示例以 Example0X 导出函数组织,无 main。可临时新建调用文件运行:
bash
cd /home/cc11001100/github/scagogogo/composer-skills/examples/cli_advanced
cat > _run.go <<'EOF'
package cli_advanced
func main() { Example01Satis() }
EOF
go run 01_satis_exec_version_diagnosis.go _run.go⚠️ 需本地安装 PHP 和 Composer,否则触发自动安装。示例路径(
/path/to/project等)为占位符,运行前请替换为真实路径;Satis 操作还需本地安装satis/satis。
📚 涉及的 SDK 方法
📝 另有
AddSatisRepository、AddSatisRequire、EnableSatisArchive、UpdateSatisStability、GetPackageVersions、ExecCommand、ExecWithWorkingDir、ArchiveWithFormat、SetVendorDir、SetBinDir、GetComposerPath、EnableInteraction等方法暂未单独建档,可参考同族已建档方法(如create-satis-config、build-satis、exec、archive、set-memory-limit、disable-interaction)的实现思路。
🚀 进阶
- 🔄 Satis CI 流水线:把
Example01Satis串成定时任务——每晚git fetch后BuildSatis并EnableSatisArchive产出 zip,维持永远最新的私有镜像。 - 🧰 工具链自检:
ExecWithList列二进制后对每个跑Exec(bin, "--version"),做 CI 前置就绪性自检脚本。 - 🩺 体检报告:
Diagnose+GetEnvironmentInfo组合输出 Markdown 报告,挂到 PR 评论或 Slack,让环境健康度可视化。 - 📦 离线交付:
Archive整项目 +ArchivePackage关键依赖组成可离线部署制品包,配合SetVendorDir适配目标机器布局。 - 🌡️ 调参矩阵:CI 矩阵遍历
SetMemoryLimit(512M/2G/-1)与SetProcessTimeout(120/600)组合,找出大依赖树解析最优配置,固化进项目config段。