8000 Feature Request: replaced-by key or ignore-if · Issue #7557 · composer/composer · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Feature Request: replaced-by key or ignore-if #7557

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

Open
BackEndTea opened this issue Aug 16, 2018 · 6 comments
Open

Feature Request: replaced-by key or ignore-if #7557

BackEndTea opened this issue Aug 16, 2018 · 6 comments
Milestone

Comments

@BackEndTea
Copy link
Contributor

Composer already has a 'replaces' key, which tells you that a package replaces another.

One thing that would be nice to have is a 'replaced-by' key, which is basically the same, but inverted. It would allow a package to specify that its replaced by another package, extension or php version.

This would mostly be relevant to polyfills, as it could specify its replaced by a certain php version or extension.

@Seldaek Seldaek added this to the Nice To Have milestone Aug 16, 2018
@Seldaek Seldaek changed the title Feature Request: replaced-by key Feature Request: replaced-by key or ignore-if Oct 26, 2020
@Seldaek
Copy link
Member
Seldaek commented Oct 26, 2020

Just as a note, symfony/polyfill#225 (comment) has alternative ideas for this, maybe it should be restricted to php/ext/lib packages too to avoid this being abused for insane stuff.

@lolli42
Copy link
lolli42 commented Aug 13, 2022

Ping.

Let me describe the main headache we have, I hope it makes sense.
I'll take symfony/polyfill-mbstring as example, but it's similar with other polyfill packages (like the phpXY ones):

One of our main package hard requires ext-mbstring extension in the 'require' section of composer.json.
This obsoletes symfony/polyfill-mbstring. However, various second level / indirect dependencies still do require symfony/polyfill-mbstring, which is why it is loaded by composer.

As a library, we can't simply set 'replace' 'symfony/polyfill-mbstring' in package composer.json since that fails as soon as a second package does the same. Also, it's semantically incorrect to do so, since our package does not provide mb_* methods as such, it just has a dependency that ensures they exist.

The only option is to set the 'replace' option on project root composer.json level to avoid loading the polyfill. Project devs however tend to forget to do that. We end up with the situation that we know that the polyfill's aren't needed, but we can't prevent projects from still loading it. In the end, many projects that require our packages end up with quite a few packages that aren't needed, but we can't do much about it as a library, except maybe improving documentation.

Is there any progress or solution in this area to mitigate this scenario?

@Seldaek
Copy link
Member
Seldaek commented Aug 17, 2022

No progress. I am still of the opinion that symfony/polyfill#225 (comment) is doable, but I am also still of the opinion that it is a dangerous feature as it may lead to packages being missing in prod if your build system has more extensions than prod for whatever reason.

Right now if you are in this case, you just install useless polyfills on the build machine but then they ensure your prod works.. And if suddenly they're gone this may break things.

As the only benefit is saving some small amount of file storage.. I am not sure it's worth the risk.

@lolli42
Copy link
lolli42 commented Aug 19, 2022

Thanks for feedback.

Your suggestion is to implement an 'ignore-if' feature on composer.json level of packages to declare "Don't load this package if ext-mbstring is loaded or if php is at least x.y". That sounds good!

I get your point this might be a risky feature: When a CI job packages a project with all dependencies to then deploy on production, it may happen that CI has for instance PHP 8.1 so some packages are skipped, but production is PHP 8.0, which would need the package.
I have the feeling, deployments based on this strategy have to take care that CI and production are similar enough already: If for instance the minor PHP version is different on CI vs. production, CI composer update would happily load symfony 6 (just as example) due to PHP 8.1 availability, which would then fail on a production PHP 8.0 environment. As such, I'd argue you're right, and additionally relying on the existence of a loaded php extension indeed makes this scenario worse, but it's essentially an existing problem that already needs to be kept in mind when following this deployment strategy.

I partially agree on "saving a small amount of file storage may not be worth the hassle, and the packages we're talking about here don't make a difference at runtime, either": Yes, it's a bit about storage, and a bit about runtime. I'd argue there are at least two more things to consider: First, code existence is always a potential security risk. When such a package has a security issue, you're not affected if you don't have it. It would be better if composer could help by not loading code that isn't needed. Secondly, from a community point of view, the current solution makes these packages much more popular than they should be - the d/l count simply does not reflect if they're really needed.

All in all, this issue may not be that important and I totally understand this hasn't been handled as 'important todo'.
I hope it's good to at least document some further thoughts on this, though.

@lolli42
Copy link
lolli42 commented Aug 27, 2024

Hey @Seldaek. I'd love to see progress here. Please ping me if you think this is possible. My company is willing to support this financially if needed.

@stof
Copy link
Contributor
stof commented Mar 31, 2025

Regarding the risk of mismatch between the prod and the build environments, I think those "ignore-if" conditions should be included in the generated platform checks if they were actually used to ignore some packages.

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

No branches or pull requests

5 participants
0