11<?php
2- declare (strict_types=1 );
2+
3+ declare (strict_types = 1 );
34
45namespace TheCodingMachine \Discovery ;
56
1011 *
1112 * @author David Negrier
1213 */
13- class PackagesOrderer {
14+ class PackagesOrderer
15+ {
1416 /**
1517 * Method: go through the tree, loading child first.
1618 * Each time we go through a package, lets ensure the package is not already part of the packages to install.
1719 * If so, ignore.
1820 *
1921 * @param PackageInterface[] $unorderedPackagesList
22+ *
2023 * @return array|PackageInterface[]
2124 */
22- public static function reorderPackages (array $ unorderedPackagesList ) : array {
23- // The very first step is to reorder the packages alphabetically.
24- // This is to ensure the same order every time, even between packages that are unrelated .
25- usort ( $ unorderedPackagesList , function ( PackageInterface $ packageA , PackageInterface $ packageB ) {
26- return strcmp ( $ packageA -> getName (), $ packageB-> getName ());
27- } );
28-
29- $ orderedPackagesList = array ();
30- foreach ( $ unorderedPackagesList as $ package ) {
31- $ orderedPackagesList = self :: walkPackagesList ( $ package , $ orderedPackagesList , $ unorderedPackagesList );
32- }
33-
34- return $ orderedPackagesList ;
35- }
36-
37- /**
38- * Function used to sort packages by dependencies (packages depending from no other package in front of others)
39- * Invariant hypothesis for this function: $orderedPackagesList is already ordered and the package we add
40- * has all its dependencies already accounted for. If not, we add the dependencies first.
41- *
42- * @param PackageInterface $package
43- * @param PackageInterface[] $orderedPackagesList The list of sorted packages
44- * @param PackageInterface[] $availablePackages The list of all packages not yet sorted
45- * @return PackageInterface[]
46- */
47- private static function walkPackagesList ( PackageInterface $ package , array $ orderedPackagesList , array & $ availablePackages ) : array {
48- // First, let's check that the package we want to add is not already in our list.
49- foreach ( $ orderedPackagesList as $ includedPackage ) {
50- if ( $ includedPackage -> equals ( $ package )) {
51- return $ orderedPackagesList ;
52- }
53- }
54-
55- // We need to make sure there is no loop (if a package A requires a package B that requires the package A)...
56- // We do that by removing the package from the list of all available packages.
57- $ key = array_search ( $ package , $ availablePackages );
58- unset( $ availablePackages [ $ key ]);
59-
60- // Now, let's see if there are dependencies.
61- foreach ( $ package -> getRequires () as $ require ) {
62- /* @var $require Link */
63- foreach ( $ availablePackages as $ iterPackage ) {
64- if ( $ iterPackage -> getName () == $ require-> getTarget () ) {
65- $ orderedPackagesList = self :: walkPackagesList ( $ iterPackage , $ orderedPackagesList , $ availablePackages );
66- break ;
67- }
68- }
69- }
70-
71- // FIXME: manage dev-requires and "provides"
72-
73- // Finally, let's add the package once all dependencies have been added.
74- $ orderedPackagesList [] = $ package ;
75-
76- return $ orderedPackagesList ;
77- }
25+ public static function reorderPackages (array $ unorderedPackagesList ) : array
26+ {
27+ // The very first step is to reorder the packages alphabetically .
28+ // This is to ensure the same order every time, even between packages that are unrelated.
29+ usort ( $ unorderedPackagesList , function ( PackageInterface $ packageA , PackageInterface $ packageB) {
30+ return strcmp ( $ packageA -> getName (), $ packageB -> getName () );
31+ });
32+
33+ $ orderedPackagesList = array ();
34+ foreach ( $ unorderedPackagesList as $ package ) {
35+ $ orderedPackagesList = self :: walkPackagesList ( $ package , $ orderedPackagesList , $ unorderedPackagesList );
36+ }
37+
38+ return $ orderedPackagesList ;
39+ }
40+
41+ /**
42+ * Function used to sort packages by dependencies (packages depending from no other package in front of others)
43+ * Invariant hypothesis for this function: $orderedPackagesList is already ordered and the package we add
44+ * has all its dependencies already accounted for. If not, we add the dependencies first.
45+ *
46+ * @param PackageInterface $package
47+ * @param PackageInterface[] $orderedPackagesList The list of sorted packages
48+ * @param PackageInterface[] $availablePackages The list of all packages not yet sorted
49+ *
50+ * @return PackageInterface[]
51+ */
52+ private static function walkPackagesList ( PackageInterface $ package , array $ orderedPackagesList, array & $ availablePackages ) : array
53+ {
54+ // First, let's check that the package we want to add is not already in our list.
55+ foreach ( $ orderedPackagesList as $ includedPackage ) {
56+ if ( $ includedPackage -> equals ( $ package )) {
57+ return $ orderedPackagesList ;
58+ }
59+ }
60+
61+ // We need to make sure there is no loop (if a package A requires a package B that requires the package A)...
62+ // We do that by removing the package from the list of all available packages.
63+ $ key = array_search ( $ package , $ availablePackages );
64+ unset( $ availablePackages [ $ key ]);
65+
66+ // Now, let's see if there are dependencies.
67+ foreach ( $ package -> getRequires () as $ require ) {
68+ /* @var $require Link */
69+ foreach ( $ availablePackages as $ iterPackage ) {
70+ if ( $ iterPackage -> getName () == $ require -> getTarget ()) {
71+ $ orderedPackagesList = self :: walkPackagesList ( $ iterPackage , $ orderedPackagesList , $ availablePackages );
72+ break ;
73+ }
74+ }
75+ }
76+
77+ // FIXME: manage dev-requires and "provides"
78+
79+ // Finally, let's add the package once all dependencies have been added.
80+ $ orderedPackagesList [] = $ package ;
7881
79- }
82+ return $ orderedPackagesList ;
83+ }
84+ }
0 commit comments