🔧 Output Parsing
Parse composer subcommands' raw text/JSON output into structured Go data — package info, outdated packages, security audit, search results, dependency tree, install/update/remove statistics, self-update, platform requirements, funding, diagnostics, config, version numbers, package name lists.
Many Composer subcommands support --format=json, but the raw JSON shapes vary (some objects, some arrays, some use package names as keys). This module normalizes these heterogeneous outputs into strongly-typed structs, and for several text-only commands (like diagnose, fund, self-update, about) does regex/indentation parsing, so you don't have to hand-write parsing logic.
When to Use
- 📊 Dashboard / CI reports: convert
install/update/outdated/auditoutput into numeric stats. - 🌳 Dependency visualization:
ParseDependencyTreeOutputconvertscomposer show --treetree text into recursively traversable[]DependencyNode. - 🔍 Retrieval:
ParseComposerSearchJSONconverts search results into structured entry lists. - 🧪 Feed fixed strings in unit tests to assert parse results without real
composercalls. - 🩺 Self-check:
ParseDiagnoseOutputAsCheckssplitsdiagnose's multi-line[OK]/[WARNING]/[ERROR]into per-item checks.
Relationship with Structured Methods
Parse Functions vs Structured Methods
Functions on this page are all package-level functions (Parse*, Extract*), with string input and struct output. They correspond one-to-one with the *Composer methods in audit, packages, version, etc. (like GetAuditInfo, GetOutdatedInfo, GetVersionInfo) — the latter are just syntactic sugar for "first c.Run(...) to get output, then call this page's Parse*". So you can either use the high-level methods or get output yourself and parse manually.
Method Signatures
| Function | Signature | Description |
|---|---|---|
| 📦 ParseComposerShowJSON | func ParseComposerShowJSON(output string) (*PackageInfo, error) | Parse show --format=json, equivalent to ParsePackageInfo |
| 🕰️ ParseComposerOutdatedJSON | func ParseComposerOutdatedJSON(output string) (*OutdatedResult, error) | Parse outdated --format=json, equivalent to ParseOutdatedResult |
| 🛡️ ParseComposerAuditJSON | func ParseComposerAuditJSON(output string) (*AuditInfoResult, error) | Parse audit --format=json, equivalent to ParseAuditInfoResult |
| 🔎 ParseComposerSearchJSON | func ParseComposerSearchJSON(output string) (*SearchResult, error) | Parse search --format=json, equivalent to ParseSearchResult |
| 🌳 ParseDependencyTreeOutput | func ParseDependencyTreeOutput(output string) ([]DependencyNode, error) | Parse show --tree text output into dependency tree |
| 🌳 ParseDependencyTreeJSON | func ParseDependencyTreeJSON(output string) ([]DependencyNode, error) | Parse show --tree --format=json dependency tree |
| ⬇️ ParseInstallOutput | func ParseInstallOutput(output string) *InstallResult | Parse install output for install/update/remove counts and warnings |
| 🔄 ParseUpdateOutput | func ParseUpdateOutput(output string) *UpdateResult | Parse update output for update counts and warnings |
| ➕ ParseRequireOutput | func ParseRequireOutput(output string, packageName string) *RequireResult | Parse require output, extract installed version |
| ➖ ParseRemoveOutput | func ParseRemoveOutput(output string, packageName string) *RemoveResult | Parse remove output and warnings |
| ⬆️ ParseSelfUpdateOutput | func ParseSelfUpdateOutput(output string) (oldVersion, newVersion string, err error) | Parse self-update output for old/new versions |
| ✅ ParseCheckPlatformReqsOutput | func ParseCheckPlatformReqsOutput(output string) ([]PlatformRequirement, error) | Parse check-platform-reqs text output |
| 💰 ParseFundOutput | func ParseFundOutput(output string) []FundInfo | Parse fund text output into funding entry list |
| 🩺 ParseDiagnoseOutputAsChecks | func ParseDiagnoseOutputAsChecks(output string) []DiagnoseCheck | Parse diagnose output into check item list |
| ⚙️ ParseConfigOutput | func ParseConfigOutput(output string) (string, error) | Parse config single-value output (whitespace trimmed) |
| 🔢 ExtractVersionFromOutput | func ExtractVersionFromOutput(output string) (string, bool) | Regex extract X.Y.Z version number from any text |
| 📛 ExtractPackageNamesFromOutput | func ExtractPackageNamesFromOutput(output string) []string | Regex extract vendor/package names from any text (deduplicated) |
Structured Return Types
PackageInfo / DependencyNode
ParseComposerShowJSON returns *PackageInfo (fields see packages); ParseDependencyTreeOutput / ParseDependencyTreeJSON return []DependencyNode:
type DependencyNode struct {
Name string `json:"name"`
Version string `json:"version,omitempty"`
Children []DependencyNode `json:"children,omitempty"`
}| Field | Type | Description |
|---|---|---|
Name | string | Package name, e.g., symfony/console |
Version | string | This node's version (may be empty) |
Children | []DependencyNode | Recursive child dependencies |
InstallResult / UpdateResult / RequireResult / RemoveResult
type InstallResult struct {
PackagesInstalled int `json:"packages_installed"`
PackagesUpdated int `json:"packages_updated"`
PackagesRemoved int `json:"packages_removed"`
Output string `json:"output"`
Warnings []string `json:"warnings,omitempty"`
}
type UpdateResult struct {
PackagesUpdated int `json:"packages_updated"`
Output string `json:"output"`
Warnings []string `json:"warnings,omitempty"`
}
type RequireResult struct {
PackageName string `json:"package_name"`
Version string `json:"version,omitempty"`
Output string `json:"output"`
Warnings []string `json:"warnings,omitempty"`
}
type RemoveResult struct {
PackageName string `json:"package_name"`
Output string `json:"output"`
Warnings []string `json:"warnings,omitempty"`
}The Output field retains raw command output for debugging; Warnings collects all lines containing Warning.
PlatformRequirement / FundInfo / DiagnoseCheck
type PlatformRequirement struct {
Package string `json:"package"`
Version string `json:"version,omitempty"`
Status string `json:"status"` // "ok" / "missing" / "mismatch"
Required string `json:"required,omitempty"`
}
type FundInfo struct {
Package string `json:"package"`
Type string `json:"type,omitempty"` // "github" / "patreon" / "tidelift", etc.
URL string `json:"url,omitempty"`
}
type DiagnoseCheck struct {
Name string `json:"name"`
Status string `json:"status"` // "ok" / "warning" / "error" / "info"
Detail string `json:"detail,omitempty"`
}Examples
Parse outdated JSON Output
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)
}
// Get raw JSON output of outdated
output, err := comp.Run("outdated", "--format", "json")
if err != nil && output == "" {
// composer may return non-zero exit code when there are no outdated packages, but output still contains valid JSON
log.Fatalf("Running outdated failed: %v", err)
}
// Use parse function to convert JSON to struct
result, err := composer.ParseComposerOutdatedJSON(output)
if err != nil {
log.Fatalf("Failed to parse outdated packages: %v", err)
}
for _, pkg := range result.Installed {
fmt.Printf("%s: installed %s -> upgradeable %s (%s)\n",
pkg.Name, pkg.Installed, pkg.Latest, pkg.LatestStatus)
}
fmt.Printf("Total outdated packages: %d\n", result.Count)
}Can Also Use High-level Methods
Above uses parse function to parse string directly. If you just want to "run command and get result", use comp.GetOutdatedInfo(), which internally is c.Run("outdated", "--format", "json") + ParseOutdatedResult.
Convert install Output to Stats
output := `Loading composer repositories with package information
Updating dependencies
Package operations: 3 installs, 0 updates, 0 removals
- Installing symfony/console (v5.4.0)
Warning: ...`
result := composer.ParseInstallOutput(output)
fmt.Printf("Installed %d, updated %d, removed %d\n",
result.PackagesInstalled, result.PackagesUpdated, result.PackagesRemoved)
// Installed 3, updated 0, removed 0
fmt.Printf("Warning count: %d\n", len(result.Warnings))Parse Dependency Tree Text Output
tree := `symfony/console v5.4.0
├── psr/log ~1.0
│ └── ...
└── symfony/polyfill-ctype v1.23.0`
nodes, err := composer.ParseDependencyTreeOutput(tree)
if err != nil {
log.Fatal(err)
}
for _, root := range nodes {
fmt.Printf("Root: %s %s, %d child dependencies\n", root.Name, root.Version, len(root.Children))
}Text vs JSON
ParseDependencyTreeOutput parses composer show --tree indented text (determines level by 4-space indent); ParseDependencyTreeJSON parses --tree --format=json. Both return the same []DependencyNode; choose based on your command invocation.
Parse self-update Output for Old/New Versions
output := "Upgrading to 2.6.6 (from 2.6.5)..."
oldVer, newVer, err := composer.ParseSelfUpdateOutput(output)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Upgraded from %s to %s\n", oldVer, newVer)
// Upgraded from 2.6.5 to 2.6.6ParseSelfUpdateOutput supports three formats: Upgrading to X (from Y), You are already using composer version X, Successfully updated to X.
Extract Version and Package Names from Arbitrary Output
text := "Detected symfony/console at version 5.4.0 in vendor/bin"
if ver, ok := composer.ExtractVersionFromOutput(text); ok {
fmt.Println("Version:", ver) // Version: 5.4.0
}
for _, name := range composer.ExtractPackageNamesFromOutput(text) {
fmt.Println("Package name:", name) // Package name: symfony/console
}ExtractVersionFromOutput uses regex (\d+\.\d+\.\d+(?:-[a-zA-Z0-9.]+)?) to match semantic version numbers (including pre-release suffix). ExtractPackageNamesFromOutput matches vendor/package pattern and deduplicates.
Parse diagnose into Per-item Checks
output := `[OK] Checking composer version
[OK] Checking platform settings
[WARNING] Checking git settings
[ERROR] Checking http connectivity`
checks := composer.ParseDiagnoseOutputAsChecks(output)
for _, c := range checks {
fmt.Printf("[%s] %s\n", c.Status, c.Name)
}
// [ok] Checking composer version
// [ok] Checking platform settings
// [warning] Checking git settings
// [error] Checking http connectivityAdvanced
Don't Confuse the Two FundInfo Types
FundInfo returned by ParseFundOutput (result_types.go, contains Package / Type / URL) comes from line-by-line parsing of fund text output; while FundingInfo on the fund page (fund.go, contains URLs slice) comes from --format=json. The two have different fields; choose based on output form.
Parseable Even on Error Exit Codes
composer outdated / audit / validate often return non-zero exit codes when issues are found, but stdout still contains valid JSON. The corresponding high-level methods (GetOutdatedInfo, etc.) handle this and continue parsing; if you directly use the Parse* functions on this page, ensure the output you pass is the actual stdout content, not err.Error().
DependencyNode Text Parsing Indentation Rules
ParseDependencyTreeOutput treats leading , |, `, - as indentation characters, with every 4 indentation characters counting as one level. So it's compatible with Composer's default tree rendering (├── / └── prefixes), but if you customize the output format you may need to switch to JSON parsing.