Skip to content

🌍 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 the composer package, and understand the difference between global and project-level operations — global commands act on COMPOSER_HOME, not the current project's vendor/.
  • 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, GlobalDumpAutoload in the composer package, plus the New and DefaultOptions constructors.
  • 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

go
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

bash
# 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 run composer global remove phpstan/phpstan to clean up.

📚 SDK Methods Involved

Method NamePackageDoc Link
Newcomposer/sdk/composer/methods/default-options
DefaultOptionscomposer/sdk/composer/methods/default-options
GlobalRequirecomposer/sdk/composer/methods/global-require
GlobalListcomposer/sdk/composer/methods/global-list
GlobalUpdatecomposer/sdk/composer/methods/global-update
GlobalRemovecomposer/sdk/composer/methods/global-remove
GlobalHomecomposer/sdk/composer/methods/get-composer-home
GlobalExecutecomposer/sdk/composer/methods/exec
GlobalStatuscomposer/sdk/composer/methods/status
GlobalInstallcomposer/sdk/composer/methods/global-install
GlobalDumpAutoloadcomposer/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 just GlobalRequire them all in one shot — no more "can't get the environment right."
  • 🔄 Variants with options: GlobalRequire/GlobalUpdate/GlobalRemove each have a *WithOptions variant that accepts params like --no-dev and --optimize-autoloader, suitable for fine-grained control of global install behavior in CI.
  • 📦 Batch operations: pair GlobalRequireMultiple and GlobalRemoveMultiple to install/remove multiple packages at once, reducing the overhead of repeatedly invoking the composer binary.
  • 🗂️ Global-state patrol: periodically call GlobalStatus and GlobalList, compare against a baseline snapshot, and detect unexpected tampering with the global environment.
  • 🐳 Image-layer caching: in a Dockerfile, first GlobalRequire the tools, then GlobalDumpAutoload(true) to optimize the autoloader, freezing the global toolchain into an image layer to speed up subsequent container starts.

Released under the MIT License