8000 Suggest polyfill packages providing an extension when it is missing. · Issue #11669 · composer/composer · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Suggest polyfill packages providing an extension when it is missing. #11669

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
stof opened this issue Sep 30, 2023 · 6 comments · Fixed by #12113
Closed

Suggest polyfill packages providing an extension when it is missing. #11669

stof opened this issue Sep 30, 2023 · 6 comments · Fixed by #12113
Labels
Milestone

Comments

@stof
Copy link
Contributor
stof commented Sep 30, 2023

Disclaimer: I'm using mbstring as an example here, but this applies to any extension.

When a package requires ext-mbstring and you don't have it, the output currently looks like that:

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Root composer.json requires PHP extension ext-mbstring * but it is missing from your system. Install or enable PHP's mbstring extension.

To enable extensions, verify that they are enabled in your .ini files:
    - /etc/php/8.2/cli/php.ini
You can also run `php --ini` in a terminal to see which files are used by PHP in CLI mode.
Alternatively, you can run Composer with `--ignore-platform-req=ext-mbstring` to temporarily ignore these required extensions.

Installing the mbstring extension is indeed the best solution in term of performance. However, there is another alternative if you cannot install the extension: installing a polyfill package that provides the API implemented in PHP. For instance, symfony/polyfill-mbstring provides it for ext-mbstring.

The providers-api-url of Packagist works fine for those extension packages. For instance, the list of packages providing ext-mbstring is at https://packagist.org/providers/ext-mbstring.json
So it would be great if Composer could load it and display an alternative solution based on installing a polyfill package.

@stof
Copy link
Contributor Author
stof commented Sep 30, 2023

For context, the Symfony packages are currently defining a requirement on symfony/polyfill-mbstring instead of requiring ext-mbstring. There is 2 reasons for that:

  • an historical reason: Composer 1 was not properly supporting packages that provide an extension in its dependency solver. It was working only if the package was already installed in the vendor directory. This is solved in Composer 2.
  • a DX reason: it makes it easier to install those packages when you don't have the extension installed.

The big drawback of this approach is that it wastes both bandwidth, disk space and some time loading the bootstrapping files (there is no function autoloading so this is not lazy) for all projects that do have the extension installed, which is the recommended setup. This can be solved by the replace trick usable by projects (not by libraries) to mark the polyfill package as replaced thanks to requiring the native extension.

My suggestion would allow solving the DX reason even for packages that require ext-mbstring, allowing to avoid bringing the polyfill in projects that don't need it by switching packages to require ext-mbstring. And it would provide the similar DX improvement when attempting to install any other package that requires ext-mbstring already.

@Seldaek Seldaek added the Feature label Oct 2, 2023
@Seldaek Seldaek added this to the 2.7 milestone Oct 2, 2023
@glaubinix
Copy link
Contributor

I am not sure if this really is an issue, but I guess polyfills currently also help users that run composer update on machines that have more PHP extensions enabled than their production environment. They currently don't notice that they are missing extensions on their production servers because the polyfills hide this.

Can probably be solved by frameworks and libraries recommending to run composer check on deploy once they drop the polyfills from their required packages.

@stof
Copy link
Contributor Author
stof commented Oct 2, 2023

@glaubinix if you run composer install as part of your deployment pipeline, Composer will already check that. And if you don't do it, you should indeed run composer check. But that's true even without this proposal of a better error message on failures.

@glaubinix
Copy link
Contributor

Definitely agree with that and I fully support the feature. I just had a feeling that moving away from adding polyfills by default might result in support requests where people suddenly run into broken deployments.

@naderman
Copy link
Member

Problems I see with this and why I'll close it:

  • I agree that a solution to installing polyfills that requires reading an error message and manually running additional commands doesn't provide the DX that we're looking for with polyfills
  • We can't just blindly pick any polyfill cause it would violate our security principle of only installing packages that are explicitly required. Additionally how do you pick a polyfill for e.g. ext-mbstring from this list https://packagist.org/providers/ext-mbstring The only real alternative to fix this would be a new "trust-package" relationship in addition to require, so that packages can declare trust for a particular polyfill without requiring it.
  • Now even if we make that work, if packages only need to require "php: ^9" or "ext-foo" and that is supposed to magically install the polyfill if the ext or that php version isn't present, we'll run into problems, because none of these polyfills cover 100% of the extension or php version functionality. So e.g. packages that work with the subset of php 9 that is provided by a php9 polyfill will still need to explicitly require that polyfill to make it clear they don't require other parts of php not provided by that particular polyfill.

As a consequence, the only way I see this working is allowing polyfills to declare that a particular php version or extension entirely replaces them and makes them unnecessary to install. But we can't have polyfills automatically fill in for ext or php version requirements.

There is ongoing discussion on a potential solution to that latter idea in #7557 so closing this here.

@naderman naderman closed this as not planned Won't fix, can't repro, duplicate, stale Sep 17, 2024
@naderman
Copy link
Member

Going to reopen this, cause we can still add the list of polyfills as a suggestion like we already do for other providers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants
0