Skip to content

Improved package sorting #2644

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

Merged
merged 2 commits into from
Feb 6, 2014

Conversation

olvlvl
Copy link
Contributor

@olvlvl olvlvl commented Jan 29, 2014

Hi,

While I was trying to resolve an issue that caused files defined by a same package to be scattered across the autoload files array, I noticed that the package sorting algorithm needed to be improved because the position (or importance) of the packages wasn't computed recursively and the resulting positions were sorted using asort which produced unpredictable results for packages with the same position, because as you know the sorting algorithm used by PHP is not stable (from the manual: If two members compare as equal, their relative order in the sorted array is undefined).

This new algorithm has two purpose: compute positions (or weights) recursively, so that a package required by a package of weight -10 has at least a weight of -11; use a stable sorting algorithm so that the order of packages with the same weight is preserved.

The following is a comparison of the current algorithm with the proposal algorithm. I'm using the icybee/modules-nodes 2.x for testing purpose, because testing the package with the current Composer is causing a fatal error since the files of the icanboogie/http package are loaded after the files of the icanboogie/icanboogie package, although icanboogie/icanboogie requires icanboogie/http.

PACKAGES SORTED CURRENT SORTED PROPOSAL
icanboogie/module-installer icanboogie/module-installer (-7) icanboogie/common (-81)
ircmaxell/password-compat ircmaxell/password-compat (-6) icanboogie/inflector (-35)
brickrouge/css-class-names brickrouge/css-class-names (-5) icanboogie/prototype (-27)
icanboogie/inflector icanboogie/inflector (-4) icanboogie/datetime (-24)
icanboogie/common icanboogie/common (-3) icanboogie/event (-21)
icanboogie/event icanboogie/event (-2) icanboogie/http (-13)
icanboogie/datetime icanboogie/datetime (-1) icanboogie/errors (-9)
icanboogie/prototype icanboogie/prototype (0) icanboogie/activerecord (-7)
icanboogie/activerecord icanboogie/activerecord (1) icanboogie/routing (-6)
icybee/module-users icanboogie/module (6) icanboogie/operation (-3)
icybee/module-sites icanboogie/operation (6) icanboogie/module-installer (-2)
icanboogie/errors icanboogie/routing (7) icanboogie/module (-2)
icanboogie/module icanboogie/errors (7) ircmaxell/password-compat (-1)
icanboogie/http icanboogie/icanboogie (7) brickrouge/css-class-names (-1)
icanboogie/routing icanboogie/http (7) icanboogie/icanboogie (-1)
icanboogie/operation icybee/module-users (9) icybee/module-users (0)
icanboogie/icanboogie icybee/module-sites (10) icybee/module-sites (0)
icybee/core icybee/core (17) icybee/core (0)

With this proposal, icanboogie/common is rightfully at the top since it is used by many packages, although sometimes indirectly; and icanboogie/http is well before icanboogie/icanboogie since it is used by icanboogie/routing and icanboogie/icanboogie and by other packages as well although indirectly. Also notice that the order of packages with the same weight is preserved.

Note: This pull request is similar to the PR #2642, but it features only the diff for the sortPackageMap() mehtod.

@olvlvl olvlvl mentioned this pull request Jan 29, 2014
$computing = array();
$computed = array();
$compute_importance = function($name) use(&$compute_importance, &$computing, &$computed, $usageList) {
# reusing computed importance
Copy link
Contributor

Choose a reason for hiding this comment

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

please use // for comments, not #

@stof
Copy link
Contributor

stof commented Jan 29, 2014

Is it really needed to use a stable sort ? If 2 packages have the same weight, we don't care about the order in which their files are loaded, as it means that they don't depend on each other. So the unstable sort written in C should be enough for us.

@olvlvl
Copy link
Contributor Author

olvlvl commented Jan 29, 2014

About stable sort: Although packages might not depend from one another, one might want them to be defined in a certain order. Imagine two unrelated packages patching the helper of a third package. Using stable sort, the developer is able to choose which should overwrite the helper in the end. But you're right, it might not be as important as it is with the current algorithm.

@Seldaek
Copy link
Member

Seldaek commented Feb 6, 2014

I think the stable sort is quite important actually because packages on top in your composer.json should be reuqired first. It was already a problem in the past, so I guess this new algo will still work for that use case, while improving the dependency sort.

@Seldaek
Copy link
Member

Seldaek commented Feb 6, 2014

Merging since it seems reasonable, let's hope it doesn't backfire. Thanks!

@olvlvl
Copy link
Contributor Author

olvlvl commented Feb 6, 2014

Yes, let's hope :)

I just noticed that the permissions of the files were changed from 100644 to 100755 by my commit. Sorry about that.

Also, did you have time to review my PR for the issue #2615 ?

Seldaek added a commit that referenced this pull request Feb 6, 2014
@Seldaek Seldaek merged commit 1727899 into composer:master Feb 6, 2014
@Seldaek
Copy link
Member

Seldaek commented Feb 6, 2014

Yeah I fixed the mode while merging no worries, regarding the other issue I'll try to review again but don't have so much time.

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

Successfully merging this pull request may close these issues.

3 participants