Skip to content
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

Fix PoolOptimizer should consider disjunctive MultiConstraints #10579

Merged
merged 8 commits into from
Mar 12, 2022

Conversation

Toflar
Copy link
Contributor

@Toflar Toflar commented Feb 28, 2022

Fixes #10558

The problem is that we're currently only generating one "dependency constraint group" for disjunctive MultiConstraint instances. This means that for ^2.14 || ^3.3 we only keep one package that matches this constraint. However, this can go bad as e.g. 3.3.0 goes missing in favor of 2.14.0 for --prefer-lowest which might cause an unresolvable set of dependencies whereas 3.3.0 would have actually led to a solution.

If a MultiConstraint is disjunctive, we need to create individual groups for every sub constraint.

@Toflar Toflar marked this pull request as draft February 28, 2022 16:56
@Toflar Toflar marked this pull request as ready for review February 28, 2022 23:15
@Toflar Toflar changed the title Fix PoolOptimizer being too aggressive Fix PoolOptimizer should consider disjunctive MultiConstraints Feb 28, 2022
@Toflar
Copy link
Contributor Author

Toflar commented Feb 28, 2022

@emodric and @Seldaek: I think this is ready to review/test. It's kind of funny nobody noticed this yet :)
Failing test looks unrelated.


if ($constraint instanceof MultiConstraint && $constraint->isDisjunctive()) {
foreach ($constraint->getConstraints() as $sub) {
$expanded = array_merge($expanded, $this->expandDisjunctiveMultiConstraints($sub));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the recursion here needed vs simply $expanded[] = $sub;? I don't think we ever create nested disjunctive constraints but maybe I'm overlooking something.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's one of my questions ;) I don't know if it's even possible to define something like (^2.0 || ^3.0) || (^4.1 || ^2.1)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It technically is possible I think, although very uncommon. But we do currently allow multiconstraints to be arbitrarily nested.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try to work on another testcase then. I want to have this covered.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Brackets are not allowed in version constraints so I don't know how I could create this. I also tried in an actual project and there was no case 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It already is. I just left a comment there to maybe give our future selves an idea where to start debugging if something like this happens. Might want to remove the TODO or rephrase but I think you have to decide how you'd like to have that note :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah indeed, compact constraint will never have nested disjunction in the output. Disjunction is only used on top level to basically list all the intervals.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With that knowledge in mind, we can also drop the hint (and the time-consuming test if you want 😢) 😉 Just let me know what to do :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry had missed that compact was called :( I'd remove it then and maybe just leave a comment that because of the compact that can't exist there?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No prob, it helped us find out that it's not a use case so that's good :) This PR is now finished then, I guess.

@Seldaek
Copy link
Member

Seldaek commented Mar 1, 2022

Thanks for the fix, it makes sense I think. I suppose the perf regression isn't too bad as this kind of constraints isn't so widespread?

@Seldaek Seldaek requested a review from naderman March 1, 2022 08:49
@Seldaek Seldaek added this to the 2.2 milestone Mar 1, 2022
@Toflar
Copy link
Contributor Author

Toflar commented Mar 1, 2022

I could not see any regression, no. I actually tested that :) According to blackfire there are other parts that require far more time which is something I want to investigate but that was already the case before this PR.

@emodric
Copy link

emodric commented Mar 1, 2022

I cannot comment in implementation, but I tested the fix on example composer.json from the issue and on the real life project composer.json and install works fine 👍

@Seldaek Seldaek added the Bug label Mar 1, 2022
@Toflar
Copy link
Contributor Author

Toflar commented Mar 2, 2022

Failing test again unrelated.

@Seldaek Seldaek merged commit ced24da into composer:2.2 Mar 12, 2022
@Seldaek
Copy link
Member

Seldaek commented Mar 12, 2022

Thanks!

@Toflar Toflar deleted the fix/pool-optimizer-too-aggressive branch March 14, 2022 07:29
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 this pull request may close these issues.

4 participants