Sort packages with the same weight alphabetically to have a completely stable sort not dependent on input order, fixes #10614
parent
d67953266f
commit
f31700bf19
|
@ -1379,7 +1379,7 @@ INITIALIZER;
|
||||||
/**
|
/**
|
||||||
* Sorts packages by dependency weight
|
* Sorts packages by dependency weight
|
||||||
*
|
*
|
||||||
* Packages of equal weight retain the original order
|
* Packages of equal weight are sorted alphabetically
|
||||||
*
|
*
|
||||||
* @param array<int, array{0: PackageInterface, 1: string}> $packageMap
|
* @param array<int, array{0: PackageInterface, 1: string}> $packageMap
|
||||||
* @return array<int, array{0: PackageInterface, 1: string}>
|
* @return array<int, array{0: PackageInterface, 1: string}>
|
||||||
|
|
|
@ -20,7 +20,7 @@ class PackageSorter
|
||||||
/**
|
/**
|
||||||
* Sorts packages by dependency weight
|
* Sorts packages by dependency weight
|
||||||
*
|
*
|
||||||
* Packages of equal weight retain the original order
|
* Packages of equal weight are sorted alphabetically
|
||||||
*
|
*
|
||||||
* @param PackageInterface[] $packages
|
* @param PackageInterface[] $packages
|
||||||
* @return PackageInterface[] sorted array
|
* @return PackageInterface[] sorted array
|
||||||
|
@ -67,39 +67,26 @@ class PackageSorter
|
||||||
return $weight;
|
return $weight;
|
||||||
};
|
};
|
||||||
|
|
||||||
$weightList = array();
|
$weightedPackages = array();
|
||||||
|
|
||||||
foreach ($packages as $index => $package) {
|
foreach ($packages as $index => $package) {
|
||||||
$weight = $computeImportance($package->getName());
|
$name = $package->getName();
|
||||||
$weightList[$index] = $weight;
|
$weight = $computeImportance($name);
|
||||||
|
$weightedPackages[] = array('name' => $name, 'weight' => $weight, 'index' => $index);
|
||||||
}
|
}
|
||||||
|
|
||||||
$stable_sort = function (&$array) {
|
usort($weightedPackages, function ($a, $b) {
|
||||||
static $transform, $restore;
|
if ($a['weight'] !== $b['weight']) {
|
||||||
|
return $a['weight'] - $b['weight'];
|
||||||
$i = 0;
|
|
||||||
|
|
||||||
if (!$transform) {
|
|
||||||
$transform = function (&$v, $k) use (&$i) {
|
|
||||||
$v = array($v, ++$i, $k, $v);
|
|
||||||
};
|
|
||||||
|
|
||||||
$restore = function (&$v) {
|
|
||||||
$v = $v[3];
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
array_walk($array, $transform);
|
return strnatcasecmp($a['name'], $b['name']);
|
||||||
asort($array);
|
});
|
||||||
array_walk($array, $restore);
|
|
||||||
};
|
|
||||||
|
|
||||||
$stable_sort($weightList);
|
|
||||||
|
|
||||||
$sortedPackages = array();
|
$sortedPackages = array();
|
||||||
|
|
||||||
foreach (array_keys($weightList) as $index) {
|
foreach ($weightedPackages as $pkg) {
|
||||||
$sortedPackages[] = $packages[$index];
|
$sortedPackages[] = $packages[$pkg['index']];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sortedPackages;
|
return $sortedPackages;
|
||||||
|
|
|
@ -1017,6 +1017,14 @@ EOF;
|
||||||
$packages[] = $c = new Package('c/lorem', '1.0', '1.0');
|
$packages[] = $c = new Package('c/lorem', '1.0', '1.0');
|
||||||
$packages[] = $e = new Package('e/e', '1.0', '1.0');
|
$packages[] = $e = new Package('e/e', '1.0', '1.0');
|
||||||
|
|
||||||
|
// expected order:
|
||||||
|
// c requires nothing
|
||||||
|
// d requires c
|
||||||
|
// b requires c & d
|
||||||
|
// e requires c
|
||||||
|
// z requires c
|
||||||
|
// (b, e, z ordered alphabetically)
|
||||||
|
|
||||||
$z->setAutoload(array('files' => array('testA.php')));
|
$z->setAutoload(array('files' => array('testA.php')));
|
||||||
$z->setRequires(array('c/lorem' => new Link('z/foo', 'c/lorem', new MatchAllConstraint())));
|
$z->setRequires(array('c/lorem' => new Link('z/foo', 'c/lorem', new MatchAllConstraint())));
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,9 @@ class ComposerStaticInitFilesAutoloadOrder
|
||||||
public static $files = array (
|
public static $files = array (
|
||||||
'bfdd693009729d60c830ff8d79129635' => __DIR__ . '/..' . '/c/lorem/testC.php',
|
'bfdd693009729d60c830ff8d79129635' => __DIR__ . '/..' . '/c/lorem/testC.php',
|
||||||
'61e6098c8cafe404d6cf19e59fc2b788' => __DIR__ . '/..' . '/d/d/testD.php',
|
'61e6098c8cafe404d6cf19e59fc2b788' => __DIR__ . '/..' . '/d/d/testD.php',
|
||||||
'8bceec6fdc149a1a6acbf7ad3cfed51c' => __DIR__ . '/..' . '/z/foo/testA.php',
|
|
||||||
'c5466e580c6c2403f225c43b6a21a96f' => __DIR__ . '/..' . '/b/bar/testB.php',
|
'c5466e580c6c2403f225c43b6a21a96f' => __DIR__ . '/..' . '/b/bar/testB.php',
|
||||||
'69dfc37c40a853a7cbac6c9d2367c5f4' => __DIR__ . '/..' . '/e/e/testE.php',
|
'69dfc37c40a853a7cbac6c9d2367c5f4' => __DIR__ . '/..' . '/e/e/testE.php',
|
||||||
|
'8bceec6fdc149a1a6acbf7ad3cfed51c' => __DIR__ . '/..' . '/z/foo/testA.php',
|
||||||
'ab280164f4754f5dfdb0721de84d737f' => __DIR__ . '/../..' . '/root2.php',
|
'ab280164f4754f5dfdb0721de84d737f' => __DIR__ . '/../..' . '/root2.php',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,20 @@ class PackageSorterTest extends TestCase
|
||||||
'foo/bar6',
|
'foo/bar6',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
'equal weight sorted alphabetically' => array(
|
||||||
|
array(
|
||||||
|
$this->createPackage('foo/bar10', array('foo/dep')),
|
||||||
|
$this->createPackage('foo/bar2', array('foo/dep')),
|
||||||
|
$this->createPackage('foo/baz', array('foo/dep')),
|
||||||
|
$this->createPackage('foo/dep', array()),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'foo/dep',
|
||||||
|
'foo/bar2',
|
||||||
|
'foo/bar10',
|
||||||
|
'foo/baz',
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue