🧪 Typed return values
One of Composer Skills' core differentiators from "hand-rolled exec.Command": every meaningful command returns a structured Go type, not raw strings. This page lists the main typed return values and contrasts them with the pain of string parsing.
🔄 Structured return data flow
💔 The pain of string parsing
// The old way: get a blob of text, split it, regex it, guess column widths
out, _ := exec.Command("composer", "audit", "--format=json").Output()
// out is []byte, you have to:
// - json.Unmarshal into a struct you invent
// - guess a field name wrong → empty value
// - Composer update changes schema → silent failureNot only is it tedious to write, testing is hard: you have to mock an entire subprocess. Composer Skills defines and tests these structs for you, returning them directly.
✅ Typed return value overview
Here are the most commonly used structured return types, all from pkg/composer:
| Type | Getter method | Meaning |
|---|---|---|
🔒 AuditResult | AuditWithJSON() | Security audit result: vulnerability count, advisory list, severity levels |
📊 AuditInfo | GetAuditInfo() | Audited summary info (higher-level abstracted view) |
📦 OutdatedResult / OutdatedInfo | OutdatedPackages() / GetOutdatedInfo() | Outdated package list: current version, latest version, direct dependency flag |
🏷️ VersionInfo | GetVersionInfo() | Composer's own version information |
📋 PackageInfo | GetPackageInfo(name) | Structured info for an installed package |
✅ ValidateResult | ValidateStructured() | composer.json validation result: validity, error list |
🖥️ PlatformReqs | CheckPlatformReqsStructured() | Platform requirement check results (PHP version, extensions) |
📄 LicensesInfo | GetLicensesInfo() | License info for all project dependencies |
⚙️ ConfigInfo | GetConfigStructured() | Structured view of Composer config |
🔍 SearchInfo | SearchInfo(query) | Local search results |
🩺 DiagnoseInfo | DiagnoseStructured() | Structured result of composer diagnose |
Naming convention
Methods suffixed with WithJSON return the struct parsed from Composer's raw JSON (most complete fields); methods suffixed with Info or Structured return a higher-level abstracted view (easier to use). Both are type-safe.
🌰 Example: structured audit
result, err := comp.AuditWithJSON()
if err != nil {
log.Fatal(err)
}
fmt.Printf("Total vulnerabilities: %d\n", result.Found)
for _, v := range result.Advisories {
fmt.Printf(" ⚠ %s: %s\n", v.Package, v.Title)
fmt.Printf(" Severity: %s\n", v.Severity)
fmt.Printf(" CVE: %s\n", v.CVE)
fmt.Printf(" Fix version: %s\n", v.Solution)
}
// CI failure decision, one line
if result.Found > 0 {
os.Exit(1)
}Contrast with string parsing: you get result.Found (int), v.Package (string) — the compiler checks types for you, so there's no "column width changed, now my index is out of bounds".
🌰 Example: outdated package monitoring
outdated, err := comp.GetOutdatedInfo()
if err != nil {
log.Fatal(err)
}
for _, p := range outdated.Packages {
fmt.Printf("%s: %s → %s (direct: %v)\n",
p.Name, p.Version, p.Latest, p.DirectDependency)
}🌰 Example: composer.json validation
res, err := comp.ValidateStructured()
if err != nil {
log.Fatal(err)
}
if !res.Valid {
for _, e := range res.Errors {
fmt.Printf("❌ Line %d: %s\n", e.Line, e.Message)
}
}🌐 Packagist API is also typed
Both SDKs follow the same philosophy — pkg/client also returns structs:
pkg, _ := c.GetPackage("monolog/monolog")
// pkg.Package.Name / .Description / .Versions ... all structured fields
advisories, _ := c.GetSecurityAdvisories()
// advisories.Advisories is []Advisory, each with Package/Title/Severity
stats, _ := c.GetStatistics()
// stats.Packages / .Downloads are int💡 Why structured returns matter
- 🛡️ Reliability: Field names are bound by the SDK; minor Composer output tweaks won't silently break your program.
- 🧪 Testability: SDK has built-in
SetupMockOutput; inject structured expectations in tests without actually running Composer. - 🤖 Composability: After getting an
AuditResult, you can feed it directly to a report generator, CI failure check, or alerting system. - 📖 Readability:
result.Found > 0is a hundred times clearer thanstrings.Contains(out, "Vulnerabilities").
Pay attention to return type naming
Some methods end with WithJSON and return a direct mapping of Composer's raw JSON — most complete but also most "raw". If you just want a higher-level abstraction, prefer Get*Info or *Structured variants. Both return typed structs.
🧭 Next steps
- 🔒 Security audit SDK — full signature and fields for
AuditWithJSONand related methods. - ✅ Validation SDK — detailed
ValidateStructuredfield reference. - 🖥️ Platform SDK — structured platform requirement check results.
- 🌐 Packagist security advisories — structured types for remote advisories.