🌍 cli_global — Global Operations
This example demonstrates how to use the SDK to perform a full suite of global-operations maintenance on Composer's global environment: install, list, update, and remove packages, as well as get the global directory, execute global binaries, check status, and regenerate the autoloader.
📌 Example Positioning
- Learning objective: Master all
Global*methods in thecomposerpackage, and understand the difference between global and project-level operations — global commands act onCOMPOSER_HOME, not the current project'svendor/. - Corresponding scenarios: globally install CLI tools (e.g.
phpstan,php-cs-fixer), uniformly upgrade the global toolchain, pre-install common binaries in CI images, and query the global environment's status. - Corresponding SDK methods:
GlobalRequire,GlobalList,GlobalUpdate,GlobalRemove,GlobalHome,GlobalExecute,GlobalStatus,GlobalInstall,GlobalDumpAutoloadin thecomposerpackage, plus theNewandDefaultOptionsconstructors. - Prerequisites: PHP 7.4+ and Composer 2.0+ installed locally. Global operations modify
COMPOSER_HOME, so running them in a resettable environment (container/VM) is recommended.
📜 Full Code
package cli_global
import (
"fmt"
"log"
"github.com/scagogogo/composer-skills/pkg/composer"
)
// Example01GlobalOperations demonstrates how to use global Composer operations
func Example01GlobalOperations() {
c, err := composer.New(composer.DefaultOptions())
if err != nil {
log.Fatalf("Failed to create Composer instance: %v", err)
}
// Example 1: Globally install a package
fmt.Println("1. Globally installing a package...")
err = c.GlobalRequire("phpstan/phpstan", "^1.0")
if err != nil {
log.Printf("Failed to install package globally: %v", err)
} else {
fmt.Println("Global install succeeded")
}
// Example 2: List globally installed packages
fmt.Println("\n2. Listing globally installed packages...")
output, err := c.GlobalList()
if err != nil {
log.Printf("Failed to get global package list: %v", err)
} else {
fmt.Println(output)
}
// Example 3: Globally update packages
fmt.Println("\n3. Globally updating packages...")
err = c.GlobalUpdate([]string{"phpstan/phpstan"})
if err != nil {
log.Printf("Global update failed: %v", err)
} else {
fmt.Println("Global update succeeded")
}
// Example 4: Globally remove a package
fmt.Println("\n4. Globally removing a package...")
err = c.GlobalRemove("phpstan/phpstan")
if err != nil {
log.Printf("Global remove failed: %v", err)
} else {
fmt.Println("Global remove succeeded")
}
// Example 5: Get the global directory path
fmt.Println("\n5. Getting the global directory path...")
output, err = c.GlobalHome()
if err != nil {
log.Printf("Failed to get global directory: %v", err)
} else {
fmt.Printf("Global directory: %s\n", output)
}
// Example 6: Execute a globally installed binary
fmt.Println("\n6. Executing a globally installed binary...")
output, err = c.GlobalExecute("phpstan", "analyse", "--no-progress")
if err != nil {
log.Printf("Failed to execute global command: %v", err)
} else {
fmt.Println(output)
}
// Example 7: Check global package status
fmt.Println("\n7. Checking global package status...")
output, err = c.GlobalStatus()
if err != nil {
log.Printf("Failed to get global status: %v", err)
} else {
fmt.Println(output)
}
// Example 8: Globally install dependencies
fmt.Println("\n8. Globally installing dependencies...")
err = c.GlobalInstall()
if err != nil {
log.Printf("Failed to install global dependencies: %v", err)
} else {
fmt.Println("Global dependencies installed successfully")
}
// Example 9: Globally regenerate the autoloader
fmt.Println("\n9. Globally regenerating the autoloader...")
err = c.GlobalDumpAutoload(true)
if err != nil {
log.Printf("Failed to regenerate global autoloader: %v", err)
} else {
fmt.Println("Global autoloader generated")
}
}🧠 Code Walkthrough
Creating the instance
🔧 Create the instance with composer.New(composer.DefaultOptions()). Global operations do not depend on WorkingDir — they act on COMPOSER_HOME, so unlike project-level examples, there's no need to call SetWorkingDir.
Global CRUD (examples 1/3/4)
📥 GlobalRequire("phpstan/phpstan", "^1.0") is equivalent to composer global require — it writes the package into the global composer.json and installs it; the second argument is the version constraint.
🔄 GlobalUpdate([]string{"phpstan/phpstan"}) updates only the specified packages; pass an empty slice to update all global packages, equivalent to composer global update.
🗑️ GlobalRemove("phpstan/phpstan") removes the package from the global environment and cleans up its dependencies, equivalent to composer global remove.
Global queries (examples 2/5/7)
📋 GlobalList() returns a text listing of globally installed packages (the raw output of composer global list), suitable for direct printing or log archiving.
🏠 GlobalHome() returns the COMPOSER_HOME path, locating files like the global vendor/ and composer.json — a common entry point for downstream custom scripts.
📊 GlobalStatus() shows the local modifications of global packages (composer global status), useful for detecting whether the global environment has been hand-edited.
Execution and maintenance (examples 6/8/9)
⚡ GlobalExecute("phpstan", "analyse", "--no-progress") directly invokes a globally installed binary, equivalent to composer global exec phpstan -- analyse --no-progress. This is the key entry point for incorporating the Composer global toolchain into automation scripts.
📦 GlobalInstall() runs composer global install based on the global composer.json, commonly used to restore the global toolset on a fresh machine.
🧩 GlobalDumpAutoload(true) regenerates the global autoloader; true enables optimization (optimized classmap), equivalent to composer global dump-autoload --optimize.
Error-handling style
⚠️ Note that this example adopts a "on failure, only log.Printf and continue to the next step" strategy for each call, convenient for demonstrating all methods in one pass. In production, failures on critical steps like install/remove should typically short-circuit return to avoid running subsequent commands in an abnormal state.
▶️ How to Run
# Run from the repository root
cd /home/cc11001100/github/scagogogo/composer-skills
# Run the cli_global example (requires PHP and Composer installed locally)
go run examples/cli_global/01_global_operations.go💡 Global operations will actually modify your machine's
COMPOSER_HOME. If you're worried about polluting your local environment, run it in a container; if Composer is not installed locally, the SDK triggers the auto-install flow.⚠️ Example 1 globally installs
phpstan/phpstan, and example 4 removes it — if interrupted midway, a global package may be left behind. You can manually runcomposer global remove phpstan/phpstanto clean up.
📚 SDK Methods Involved
| Method Name | Package | Doc Link |
|---|---|---|
New | composer | /sdk/composer/methods/default-options |
DefaultOptions | composer | /sdk/composer/methods/default-options |
GlobalRequire | composer | /sdk/composer/methods/global-require |
GlobalList | composer | /sdk/composer/methods/global-list |
GlobalUpdate | composer | /sdk/composer/methods/global-update |
GlobalRemove | composer | /sdk/composer/methods/global-remove |
GlobalHome | composer | /sdk/composer/methods/get-composer-home |
GlobalExecute | composer | /sdk/composer/methods/exec |
GlobalStatus | composer | /sdk/composer/methods/status |
GlobalInstall | composer | /sdk/composer/methods/global-install |
GlobalDumpAutoload | composer | /sdk/composer/methods/dump-autoload |
About the links
GlobalHome, GlobalExecute, GlobalStatus, and GlobalDumpAutoload don't yet have standalone method pages; the links above point to their project-level counterparts (GetComposerHome, Exec, Status, DumpAutoload). The parameter semantics are identical — only the scope switches from the project directory to the global COMPOSER_HOME.
🚀 Going Further
- 🧰 Global toolchain as code: write the team's agreed-upon global tools (
phpstan,php-cs-fixer,psalm, etc.) and version constraints into a Go program; new members justGlobalRequirethem all in one shot — no more "can't get the environment right." - 🔄 Variants with options:
GlobalRequire/GlobalUpdate/GlobalRemoveeach have a*WithOptionsvariant that accepts params like--no-devand--optimize-autoloader, suitable for fine-grained control of global install behavior in CI. - 📦 Batch operations: pair
GlobalRequireMultipleandGlobalRemoveMultipleto install/remove multiple packages at once, reducing the overhead of repeatedly invoking the composer binary. - 🗂️ Global-state patrol: periodically call
GlobalStatusandGlobalList, compare against a baseline snapshot, and detect unexpected tampering with the global environment. - 🐳 Image-layer caching: in a Dockerfile, first
GlobalRequirethe tools, thenGlobalDumpAutoload(true)to optimize the autoloader, freezing the global toolchain into an image layer to speed up subsequent container starts.