Skip to content

⚡ Convenience Methods

A set of high-level wrappers that consolidate common operations like "determine project status", "read composer.json/lock", "list installed packages/direct dependencies", "filter by type/abandoned", "namespace/script queries", and "directory location" into one-line calls.

Most of these methods directly read files or combine multiple composer subcommands, saving you from hand-writing parsing logic. They fall into three categories: 🩺 status checks, 📊 project summaries, 🔍 directory and config queries.

When to Use

  • 🩺 Quickly determine if the current directory is a Composer project and whether dependencies are installed at startup.
  • 📊 Generate a project health report: dependency count, outdated package count, vulnerability count, Composer/PHP version — all in one GetProjectSummary call.
  • 📋 List installed package names or direct dependency names for dependency analysis scripts.
  • 🎯 Filter packages by type (find all composer-plugin) or find abandoned packages.
  • 🗂️ Get vendor/bin/cache/home directory paths to plan cache or artifacts.

Structured Types

ProjectSummary

Returned by GetProjectSummary, a project health report aggregating multi-source information.

go
type ProjectSummary struct {
	Name                  string `json:"name,omitempty"`
	Description           string `json:"description,omitempty"`
	Type                  string `json:"type,omitempty"`
	License               string `json:"license,omitempty"`
	DirectDependencyCount int    `json:"direct_dependency_count"`
	DevDependencyCount    int    `json:"dev_dependency_count"`
	TotalInstalledCount   int    `json:"total_installed_count"`
	OutdatedCount         int    `json:"outdated_count"`
	VulnerabilityCount    int    `json:"vulnerability_count"`
	ComposerVersion       string `json:"composer_version,omitempty"`
	PHPVersion            string `json:"php_version,omitempty"`
}

ProjectDependencies

Returned by GetProjectDependencies, dependency counts and package name lists.

go
type ProjectDependencies struct {
	DirectCount       int      `json:"direct_count"`
	DevCount          int      `json:"dev_count"`
	TotalInstalled    int      `json:"total_installed"`
	DirectPackages    []string `json:"direct_packages,omitempty"`
	DevPackages       []string `json:"dev_packages,omitempty"`
	InstalledPackages []string `json:"installed_packages,omitempty"`
}

Method Signatures

🩺 Status Checks

MethodSignatureDescription
📦 IsProjectfunc (c *Composer) IsProject() boolWhether current working directory has composer.json
📂 IsProjectInfunc (c *Composer) IsProjectIn(dir string) boolWhether specified directory has composer.json
🔒 HasComposerLockfunc (c *Composer) HasComposerLock() boolWhether composer.lock exists
📁 HasVendorDirfunc (c *Composer) HasVendorDir() boolWhether vendor directory exists
✅ IsPackageInstalledfunc (c *Composer) IsPackageInstalled(packageName string) boolWhether a package is installed
🧪 IsPackageDevfunc (c *Composer) IsPackageDev(packageName string) (bool, error)Whether a package is in require-dev

📊 Project Summary and Dependencies

MethodSignatureDescription
📋 GetInstalledPackageNamesfunc (c *Composer) GetInstalledPackageNames() ([]string, error)All installed package names
🎯 GetDirectDependencyNamesfunc (c *Composer) GetDirectDependencyNames() ([]string, error)Direct dependency package names
🔢 GetPackageVersionsListfunc (c *Composer) GetPackageVersionsList(packageName string) ([]string, error)All available versions of a package
📊 GetProjectDependenciesfunc (c *Composer) GetProjectDependencies() (*ProjectDependencies, error)Dependency summary
📈 GetProjectSummaryfunc (c *Composer) GetProjectSummary() (*ProjectSummary, error)Project health report
🔖 GetRequireWithVersionfunc (c *Composer) GetRequireWithVersion(packageName string) (string, error)Installed version of a package
🏷️ GetPackagesByTypefunc (c *Composer) GetPackagesByType(packageType string) ([]string, error)Filter packages by type
⚠️ GetAbandonedPackagesFromLockfunc (c *Composer) GetAbandonedPackagesFromLock() ([]string, error)Find abandoned packages from lock
🗺️ GetNamespaceMapfunc (c *Composer) GetNamespaceMap() (map[string]string, error)PSR-4 namespace → directory mapping
📜 GetScriptsfunc (c *Composer) GetScripts() (map[string]interface{}, error)composer.json scripts

🗂️ Directory and File Reading

MethodSignatureDescription
🏠 GetComposerHomeDirfunc (c *Composer) GetComposerHomeDir() (string, error)composer config home
💾 GetCacheDirfunc (c *Composer) GetCacheDir() (string, error)composer config cache-dir
📦 GetVendorDirfunc (c *Composer) GetVendorDir() (string, error)vendor directory (with fallback default)
🗂️ GetBinDirfunc (c *Composer) GetBinDir() (string, error)bin directory (with fallback default)

🔧 Package-level Parse Functions

MethodSignatureDescription
📋 ParsePackageListfunc ParsePackageList(output string) []stringParse composer show text output
🔢 ParsePackageVersionsfunc ParsePackageVersions(output string) ([]string, error)Parse versions from show --all --format=json

Examples

Project Health Report

go
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)
	}

	summary, err := comp.GetProjectSummary()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("📦 %s (%s)\n", summary.Name, summary.Type)
	fmt.Printf("   Direct deps %d / Dev deps %d / Installed %d\n",
		summary.DirectDependencyCount, summary.DevDependencyCount, summary.TotalInstalledCount)
	fmt.Printf("   Outdated %d / Vulnerabilities %d\n", summary.OutdatedCount, summary.VulnerabilityCount)
	fmt.Printf("   Composer %s / PHP %s\n", summary.ComposerVersion, summary.PHPVersion)
}

List All Installed Package Names

go
pkgs, err := comp.GetInstalledPackageNames()
if err != nil {
	log.Fatal(err)
}
for _, p := range pkgs {
	fmt.Println(p)
}

Filter Packages by Type

go
plugins, err := comp.GetPackagesByType("composer-plugin")
if err != nil {
	log.Fatal(err)
}
for _, p := range plugins {
	fmt.Println("🔌", p)
}

Find Abandoned Packages

go
abandoned, err := comp.GetAbandonedPackagesFromLock()
if err != nil {
	log.Fatal(err)
}
if len(abandoned) > 0 {
	fmt.Println("⚠️ The following packages are abandoned, consider replacing:")
	for _, p := range abandoned {
		fmt.Println("  -", p)
	}
}

Query Installed Version of a Package

go
v, err := comp.GetRequireWithVersion("symfony/console")
if err != nil {
	log.Fatal(err)
}
fmt.Println("symfony/console version:", v)

Determine Project Status

go
if !comp.IsProject() {
	log.Fatal("Current directory is not a Composer project")
}
if !comp.HasComposerLock() {
	fmt.Println("⚠️ Missing composer.lock, recommend running composer install")
}
if !comp.HasVendorDir() {
	fmt.Println("⚠️ Missing vendor directory, dependencies not installed")
}
if comp.IsPackageInstalled("phpunit/phpunit") {
	fmt.Println("✅ PHPUnit installed")
}

Get Directory Paths

go
home, _ := comp.GetComposerHomeDir()
cache, _ := comp.GetCacheDir()
vendor, _ := comp.GetVendorDir()
bin, _ := comp.GetBinDir()
fmt.Printf("home=%s\ncache=%s\nvendor=%s\nbin=%s\n", home, cache, vendor, bin)

Using Parse Functions Independently

go
// You can run composer show yourself to get output, then use ParsePackageList to extract
output := `symfony/console    v5.4.0  Eases...
monolog/monolog    2.5.0   Sends...`
for _, name := range composer.ParsePackageList(output) {
	fmt.Println(name)
}

Advanced

GetProjectSummary Fault Tolerance

GetProjectSummary internally does err == nil checks on each sub-call — any single failure (e.g., no lock file) only leaves the corresponding field empty, without interrupting the overall report. This makes it suitable for "best-effort" health checks.

Two Abandoned Package Methods

GetAbandonedPackagesFromLock (this file) directly reads the abandoned field from composer.lock, no command execution needed; audit.go's GetAbandonedPackages goes through the composer audit command and returns []Vulnerability. The former is faster, the latter is more complete (includes extra info like abandonment reasons).

GetVendorDir / GetBinDir Fallback

When composer config vendor-dir fails (e.g., uninitialized project), they fall back to <working directory>/vendor and <working directory>/vendor/bin, not returning an error. This is intentional design, so reasonable default paths can be obtained even when the project is unconfigured.

IsPackageInstalled Determination

IsPackageInstalled executes composer show <pkg>; success means installed. Note that Composer may also return non-zero exit code when a package exists but has version issues, so this check is "optimistic".

Released under the MIT License