Skip to content

🛠️ Composer CLI SDK Overview

pkg/composer is the most central module of the Composer Skills project. It wraps the local composer binary into a type-safe, testable, auto-installing Go SDK, exposing 234 methods covering dependency management, package operations, project creation, configuration, repositories, auditing, diagnostics, platform checks, version constraints, and almost all Composer CLI capabilities.

If you only remember one entry point, it's Core Runtime: get a *Composer via composer.New(composer.DefaultOptions()), and all methods are attached to it.

📦 Module Positioning

  • 📦 Package path: github.com/scagogogo/composer-skills/pkg/composer
  • 🛠️ Core type: Composer (struct, not interface; method set is on *Composer)
  • 🌐 Underlying mechanism: calls the local composer executable via os/exec; all command output is merged via CombinedOutput (stdout+stderr) and returned as string
  • 🔒 Testability: built-in SetupMockOutput mechanism, can inject expected output and errors for any command without actually executing composer
  • Auto-install: when composer is not detected, Options.AutoInstall=true triggers the built-in installer to fetch and install composer

🚀 Create a Composer Instance

Minimal working example — detect/auto-install composer and work in the current directory:

go
package main

import (
	"log"

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

func main() {
	comp, err := composer.New(composer.DefaultOptions())
	if err != nil {
		log.Fatalf("Failed to initialize Composer: %v", err)
	}
	// comp can now execute any composer subcommand
	if err := comp.Install(false, false); err != nil {
		log.Fatalf("Failed to install dependencies: %v", err)
	}
}

Want it simpler?

Use composer.QuickSetup(workingDir, true) (in auto_install.go) to detect, install, and create the instance in one step.

For full control over instance behavior, customize Options:

go
options := composer.Options{
	WorkingDir:     "/srv/my-app",
	AutoInstall:    true,
	DefaultTimeout: 30 * time.Minute,
	Env:            []string{"COMPOSER_HOME=/tmp/composer"},
}
comp, err := composer.New(options)

The default config returned by DefaultOptions() is: WorkingDir="" (current directory), AutoInstall=true, DefaultTimeout=10*time.Minute.

🗂️ 20 Category Overview

The table below categorizes all methods in pkg/composer by responsibility, so you can jump to the corresponding sub-doc by scenario. Method counts are approximate (including main methods and WithOptions/WithFormat variants).

CategoryMethod CountKey MethodsSub-doc
🛠️ Core Runtime11New, Run, RunWithContext, IsInstalled, SelfUpdatecore
📦 Dependencies18Install, Update, DumpAutoload, InstallWithOptions, UpdateWithLockdependencies
🔍 Packages28RequirePackage, Remove, ShowPackage, Search, OutdatedPackages, BumpPackages, WhyNotPackagepackages
➕ Extension Methods25OutdatedWithOptions, InstallDryRun, RequireMultiple, WhyWithOptions
🗜️ Archive5Archive, ArchivePackage, ArchiveWithFormat
🔒 Security Audit10Audit, AuditWithJSON, HasVulnerabilities, GetAbandonedPackagesaudit
✅ Auto-install6EnsureInstalled, QuickSetup, SelfUpdateWithProgress
⌨️ Command Completion4GenerateCompletion, ListCommands, GetCommandHelp
📋 composer.json Operations11ReadComposerJSON, AddRequire, AddScript, SetConfig
⚙️ Config10ListConfig, GetConfigWithGlobal, SetConfigWithGlobal, CheckPlatformReqs
🧩 Convenience Queries27IsProject, HasComposerLock, GetDirectDependencyNames, IsPackageInstalled
🩺 Diagnosis8Diagnose, Status, Check, LocalExecdiagnosis
🌐 Environment Variables18SetEnvVariable, SetProcessTimeout, EnableSuperuser, DisableInteraction
▶️ Script Execution6Exec, ExecPHP, ExecAll, ExecWithWorkingDirexec
💰 Funding6Fund, FundWithJSON, HasFunding, GetFundingURLsfund
🌍 Global12GlobalRequire, GlobalUpdate, GlobalList, GlobalDumpAutoload
❤️ Health Check9HealthCheck, BatchRequire, BatchRemove, StatusStructured
📜 Licenses4Licenses, CheckLicenseslicenses
🔑 OAuth/Auth9GetAuthConfig, AddGitHubToken, AddGitLabToken, AddBearerTokenauth
🏗️ Platform6CheckPlatform, GetPHPVersion, HasExtension, IsPlatformAvailableplatform

Additionally, there are several independent categories (Validate validate, Version Constraints, Version version, Project project, Repository, Satis satis, archive, environment, completion, home, about, composer-json, convenience, Output Parsing parsing, etc.), see the left navigation for details.

Note: Full method signatures, parameters, return values, and examples for the "Core Runtime", "Dependencies", and "Packages" categories are detailed in core, dependencies, and packages respectively.

⚡ Quick Examples

1. Install and Lock Production Dependencies

go
comp, _ := composer.New(composer.DefaultOptions())
comp.SetWorkingDir("/srv/my-app")

// Production: skip dev dependencies + optimize autoloader
if err := comp.Install(true, true); err != nil {
	log.Fatal(err)
}
// Only refresh composer.lock hash, no package version changes
_ = comp.UpdateWithLock()

2. Add/Remove Packages and View Outdated Dependencies

go
_ = comp.RequirePackage("symfony/console", "^6.0", false)
_ = comp.Remove("old/dep", true) // Remove from require-dev

outdated, _ := comp.GetOutdatedInfo() // Structured result
for _, p := range outdated.Installed {
	fmt.Printf("%s: %s -> %s (%s)\n", p.Name, p.Installed, p.Latest, p.LatestStatus)
}

3. Query Package Info and Search with Structured Methods

go
info, _ := comp.ShowPackageInfo("monolog/monolog")
fmt.Printf("%s %s%s\n", info.Name, info.Version, info.Description)

res, _ := comp.SearchInfo("logger")
for _, r := range res.Results {
	fmt.Println(r.Name, r.Description)
}

4. Command Execution with Timeout and Cancellation

go
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
out, err := comp.RunWithContext(ctx, "update", "--prefer-dist")
if errors.Is(err, context.DeadlineExceeded) {
	log.Println("Update timed out")
}

🎯 Design Conventions

  • 🎯 Unified return values: All command methods either return (string, error) (get raw output) or error (only care about success); structured methods additionally return a pointer type, like (*PackageInfo, error).
  • ⚠️ Error wrapping: error returned on execution failure wraps predefined sentinel errors via fmt.Errorf("%w: ...", ErrCommandExecution, ...), making it easy to categorize with errors.Is.
  • 🧩 WithOptions pattern: Almost every command has an XxxWithOptions(options map[string]string) variant; options keys are composer long option names (without --), empty string values mean pure flag options.
  • 🧪 Mock-friendly: In tests, use SetupMockOutput("require symfony/console", "ok", nil) to inject expected output; RunWithContext hits mock first without actually calling composer.

📚 Next Steps

  • 🛠️ First read Core Runtime: understand New, Run, and auto-install/self-update mechanisms.
  • 📦 Then read Dependencies: master all variants of Install/Update.
  • 🔍 Finally read Packages: learn high-frequency operations like require/remove/show/search/outdated.
  • 🔒 For security, see Security Audit; for validation, see Validate.

Released under the MIT License