Skip to content

🚀 cli_advanced — 高级功能

本示例演示 Composer CLI 的高级能力:Satis 私有仓库构建、二进制命令执行、版本约束操作、环境诊断、项目归档,以及运行时环境变量调优。

🎯 示例定位

cli_advancedComposer CLI 本地操作 系列的压轴示例(最后一个 CLI 示例)。它把前面示例未覆盖的进阶场景一次性收口,覆盖真实工程中才会碰到的边角能力。

  • 📚 你将学到:用 SDK 驱动 Satis 私有仓库的初始化与构建;调用项目内二进制;读写版本约束;运行 diagnose/check/status 体检;归档项目与单包;调整内存、超时、Vendor/Bin 目录等运行时环境。
  • 🔗 对应 SDK 方法:InitSatis/CreateSatisConfig/BuildSatisExec/ExecPHP/ExecWithListLockPackageVersion/UpdatePackageVersion/FormatVersionConstraintDiagnose/Check/Status/GetEnvironmentInfo/GetProjectInfoArchive/ArchivePackageSetMemoryLimit/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) 用语义约束符改 requireFormatVersionConstraint 是纯函数,把裸版本号拼成 ^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.jsonconfig 段一致;🛰️ 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 方法

方法名所属包文档链接
InitSatispkg/composer/sdk/composer/methods/init-satis
CreateSatisConfigpkg/composer/sdk/composer/methods/create-satis-config
BuildSatispkg/composer/sdk/composer/methods/build-satis
Execpkg/composer/sdk/composer/methods/exec
ExecPHPpkg/composer/sdk/composer/methods/exec-php
ExecWithListpkg/composer/sdk/composer/methods/exec-with-list
LockPackageVersionpkg/composer/sdk/composer/methods/lock-package-version
UpdatePackageVersionpkg/composer/sdk/composer/methods/update-package-version
FormatVersionConstraintpkg/composer/sdk/composer/methods/format-version-constraint
Diagnosepkg/composer/sdk/composer/methods/diagnose
Checkpkg/composer/sdk/composer/methods/check
Statuspkg/composer/sdk/composer/methods/status
GetEnvironmentInfopkg/composer/sdk/composer/methods/get-environment-info
GetProjectInfopkg/composer/sdk/composer/methods/get-project-info
Archivepkg/composer/sdk/composer/methods/archive
ArchivePackagepkg/composer/sdk/composer/methods/archive-package
SetMemoryLimitpkg/composer/sdk/composer/methods/set-memory-limit
SetProcessTimeoutpkg/composer/sdk/composer/methods/set-process-timeout
DisableInteractionpkg/composer/sdk/composer/methods/disable-interaction
SetWorkingDirpkg/composer/sdk/composer/methods/set-working-dir
DefaultOptionspkg/composer/sdk/composer/methods/default-options

📝 另有 AddSatisRepositoryAddSatisRequireEnableSatisArchiveUpdateSatisStabilityGetPackageVersionsExecCommandExecWithWorkingDirArchiveWithFormatSetVendorDirSetBinDirGetComposerPathEnableInteraction 等方法暂未单独建档,可参考同族已建档方法(如 create-satis-configbuild-satisexecarchiveset-memory-limitdisable-interaction)的实现思路。

🚀 进阶

  • 🔄 Satis CI 流水线:把 Example01Satis 串成定时任务——每晚 git fetchBuildSatisEnableSatisArchive 产出 zip,维持永远最新的私有镜像。
  • 🧰 工具链自检ExecWithList 列二进制后对每个跑 Exec(bin, "--version"),做 CI 前置就绪性自检脚本。
  • 🩺 体检报告Diagnose + GetEnvironmentInfo 组合输出 Markdown 报告,挂到 PR 评论或 Slack,让环境健康度可视化。
  • 📦 离线交付Archive 整项目 + ArchivePackage 关键依赖组成可离线部署制品包,配合 SetVendorDir 适配目标机器布局。
  • 🌡️ 调参矩阵:CI 矩阵遍历 SetMemoryLimit512M/2G/-1)与 SetProcessTimeout120/600)组合,找出大依赖树解析最优配置,固化进项目 config 段。

基于 MIT 许可证发布