Discussed in #478
Originally posted by Thahun January 7, 2026
TLDR from discussion; there is no way to specify which package to install when using pie install --allow-non-interactive-project-install in a PHP project if multiple packages match.
Proposed solution & full write-up
At the moment, installing extensions for a PHP project is a little janky. This is because in a PHP project's composer.json, the extensions required are listed as ext-<ext_name> ("Extension Name" with an ext- prefix, e.g. example_pie_extension), but in PIE, we refer to extensions by their "Package Name" (e.g. asgrim/example-pie-extension to avoid ambiguity. This is because there may be a fork that someone wishes to install, instead of the primary extension.
When pie install is run in the CWD of a PHP project, it loads the composer.json/lock to determine all extensions required, and checks them one by one. If one is missing:
- In interactive mode, you are always prompted for which package to pick, even if there is one choice. This gives dev control about which package they meant
- In non-interactive mode (CI, Docker build, etc.); PIE will refuse
- In non-interactive mode with
--allow-non-interactive-project-install flag provided (dev should understand the risks here!):
- If there is one choice, PIE will automatically install the matched package
- If there is more than one choice, PIE will fail; we cannot automatically resolve the package
The proposal is to:
- Deprecate and make a no-op the
--allow-non-interactive-project-install flag (if provided, it will print out information about the change)
- Add a new flag for consumers to explicitly define packages for each extension, e.g.
pie install --select ext-redis=phpredis/phpredis --select ext-foo=asgrim/foo
- When running this, if an extension is encountered that is not installed, and not defined (e.g.
ext-bar is required), it will fail, even if only one package matches
- If an extension is encountered that is not installed and a
--select has been provided, it will use that (e.g. ext-foo will resolve to asgrim/foo)
- If an extension is encountered that is installed, the
--select is ignored
- Keep interactive mode the same; the user will be prompted for each package that is missing; unless a
--select has been passed for that package, in which case that will be used, but that is less likely to occur
The benefit here is clear: the end user has full control over which packages are installed for each extension. The non-interactive scenarios where this is needed (e.g. in CI, in a Dockerfile build, etc.), the user should not need to type these --select <def> flags out all the time, since it would be in a CI definition or Dockerfile etc, so there is only a small initial burden, but for much greater control and safety.
Future enhancements could be to define this in some kind of configuration file. This is left out of scope explicitly for now; I want to get this working in its basic form, then we can iterate later.
One "known issue" with this approach: it is not possible currently to specify configure flags for extensions installed this way. That is already the case with --allow-non-interactive-project-install flag anyway, so there is no reduction in functionality. That could be addressed in the configuration file mentioned.
Discussed in #478
Originally posted by Thahun January 7, 2026
TLDR from discussion; there is no way to specify which package to install when using
pie install --allow-non-interactive-project-installin a PHP project if multiple packages match.Proposed solution & full write-up
At the moment, installing extensions for a PHP project is a little janky. This is because in a PHP project's
composer.json, the extensions required are listed asext-<ext_name>("Extension Name" with anext-prefix, e.g.example_pie_extension), but in PIE, we refer to extensions by their "Package Name" (e.g.asgrim/example-pie-extensionto avoid ambiguity. This is because there may be a fork that someone wishes to install, instead of the primary extension.When
pie installis run in the CWD of a PHP project, it loads thecomposer.json/lockto determine all extensions required, and checks them one by one. If one is missing:--allow-non-interactive-project-installflag provided (dev should understand the risks here!):The proposal is to:
--allow-non-interactive-project-installflag (if provided, it will print out information about the change)pie install --select ext-redis=phpredis/phpredis --select ext-foo=asgrim/fooext-baris required), it will fail, even if only one package matches--selecthas been provided, it will use that (e.g.ext-foowill resolve toasgrim/foo)--selectis ignored--selecthas been passed for that package, in which case that will be used, but that is less likely to occurThe benefit here is clear: the end user has full control over which packages are installed for each extension. The non-interactive scenarios where this is needed (e.g. in CI, in a
Dockerfilebuild, etc.), the user should not need to type these--select <def>flags out all the time, since it would be in a CI definition orDockerfileetc, so there is only a small initial burden, but for much greater control and safety.Future enhancements could be to define this in some kind of configuration file. This is left out of scope explicitly for now; I want to get this working in its basic form, then we can iterate later.
One "known issue" with this approach: it is not possible currently to specify configure flags for extensions installed this way. That is already the case with
--allow-non-interactive-project-installflag anyway, so there is no reduction in functionality. That could be addressed in the configuration file mentioned.