fix(composer): set HOME and COMPOSER_HOME when spawning composer process#49
fix(composer): set HOME and COMPOSER_HOME when spawning composer process#49obinnaelviso wants to merge 2 commits into4.xfrom
Conversation
Installing/removing extensions from the admin panel failed under PHP-FPM with: "The HOME or COMPOSER_HOME environment variable must be set for composer to run correctly". Web-server users (www-data, nginx, etc.) often run with no HOME set, so Composer's Factory::getHomeDir() throws. Merge HOME and COMPOSER_HOME into the env passed to Symfony Process, pointing at the Manager's storagePath (already writable by the web user). Caller-provided env keys still take precedence.
There was a problem hiding this comment.
Pull request overview
Fixes Composer subprocess execution under PHP-FPM/web SAPIs by ensuring required home-related environment variables are present when Igniter\Flame\Composer\Manager spawns Composer via Symfony Process.
Changes:
- Inject
HOMEandCOMPOSER_HOMEinto the environment passed to the Composer subprocess (defaulting to$this->storagePath). - Add unit tests asserting default injection and caller override behavior for these env vars.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/Flame/Composer/Manager.php |
Merges default HOME/COMPOSER_HOME into the env passed to spawned Composer processes. |
tests/src/Flame/Composer/ManagerTest.php |
Adds tests covering env injection and explicit override behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| $env = array_merge([ | ||
| 'HOME' => $this->storagePath, | ||
| 'COMPOSER_HOME' => $this->storagePath, | ||
| ], $env); | ||
|
|
There was a problem hiding this comment.
getProcess() now unconditionally injects HOME/COMPOSER_HOME defaults. This likely overrides an already-set HOME inherited from the parent process (e.g., when running via CLI), which can break Composer operations that rely on the real user home directory (notably git/ssh looking up ~/.ssh). Consider only setting these variables when they are missing (both from the caller-provided $env and from the current process environment), or at least avoid overriding HOME when it is already set while still providing a fallback for web SAPIs.
| $env = array_merge([ | |
| 'HOME' => $this->storagePath, | |
| 'COMPOSER_HOME' => $this->storagePath, | |
| ], $env); | |
| if (!array_key_exists('HOME', $env) && getenv('HOME') === false) { | |
| $env['HOME'] = $this->storagePath; | |
| } | |
| if (!array_key_exists('COMPOSER_HOME', $env) && getenv('COMPOSER_HOME') === false) { | |
| $env['COMPOSER_HOME'] = $this->storagePath; | |
| } |
…them Previous patch unconditionally forced HOME and COMPOSER_HOME to storagePath, overriding values inherited from the parent process under CLI. That broke: - git/ssh package fetching, which resolves ~/.ssh via HOME - Composer auth.json, OAuth tokens, and package cache under COMPOSER_HOME Now the defaults only apply when the key is missing from both the caller-provided env and the current process environment, so the web-SAPI case still works while CLI behaviour is preserved.
Summary
Installing or updating extensions from the admin panel fails under PHP-FPM (and most web SAPIs) with:
Web-server users (
www-data,nginx, etc.) typically run with noHOMEset. WhenIgniter\Flame\Composer\Managerspawnscomposer require/composer remove/composer outdatedvia Symfony Process, Composer'sFactory::getHomeDir()has no home to discover and throws.Fix
Manager::getProcess()now mergesHOMEandCOMPOSER_HOMEinto the environment passed to the subprocess, pointing at$this->storagePath(i.e.storage/igniter/composer, already writable by the web user). Caller-provided env keys still take precedence, so behaviour is unchanged when an env is explicitly passed.Diff is 5 lines of production code + 2 new tests.
Test plan
vendor/bin/pint --dirty→ passesvendor/bin/phpstan analyse→ no new errors (existing baseline errors in unrelated files remain)