1
0
Fork 0

Make sure Transaction sorts operations correctly to begin with

pull/9339/head
Jordi Boggiano 2020-10-25 14:06:45 +01:00
parent dc88236c07
commit 2d4e1e0dce
No known key found for this signature in database
GPG Key ID: 7BBD42C429EC80BC
3 changed files with 55 additions and 2 deletions

View File

@ -248,6 +248,9 @@ class Transaction
*/ */
private function movePluginsToFront(array $operations) private function movePluginsToFront(array $operations)
{ {
$dlModyingPluginsNoDeps = array();
$dlModyingPluginsWithDeps = array();
$dlModyingPluginRequires = array();
$pluginsNoDeps = array(); $pluginsNoDeps = array();
$pluginsWithDeps = array(); $pluginsWithDeps = array();
$pluginRequires = array(); $pluginRequires = array();
@ -261,6 +264,30 @@ class Transaction
continue; continue;
} }
$isDownloadsModifyingPlugin = $package->getType() === 'composer-plugin' && ($extra = $package->getExtra()) && isset($extra['plugin-modifies-downloads']) && $extra['plugin-modifies-downloads'] === true;
// is this a downloads modifying plugin or a dependency of one?
if ($isDownloadsModifyingPlugin || count(array_intersect($package->getNames(), $dlModyingPluginRequires))) {
// get the package's requires, but filter out any platform requirements
$requires = array_filter(array_keys($package->getRequires()), function ($req) {
return !PlatformRepository::isPlatformPackage($req);
});
// is this a plugin with no meaningful dependencies?
if ($isPlugin && !count($requires)) {
// plugins with no dependencies go to the very front
array_unshift($dlModyingPluginsNoDeps, $op);
} else {
// capture the requirements for this package so those packages will be moved up as well
$dlModyingPluginRequires = array_merge($dlModyingPluginRequires, $requires);
// move the operation to the front
array_unshift($dlModyingPluginsWithDeps, $op);
}
unset($operations[$idx]);
continue;
}
// is this package a plugin? // is this package a plugin?
$isPlugin = $package->getType() === 'composer-plugin' || $package->getType() === 'composer-installer'; $isPlugin = $package->getType() === 'composer-plugin' || $package->getType() === 'composer-installer';
@ -286,7 +313,7 @@ class Transaction
} }
} }
return array_merge($pluginsNoDeps, $pluginsWithDeps, $operations); return array_merge($dlModyingPluginsNoDeps, $dlModyingPluginsWithDeps, $pluginsNoDeps, $pluginsWithDeps, $operations);
} }
/** /**

View File

@ -240,7 +240,7 @@ class InstallationManager
foreach ($operations as $index => $operation) { foreach ($operations as $index => $operation) {
if (in_array($operation->getOperationType(), array('update', 'install'), true)) { if (in_array($operation->getOperationType(), array('update', 'install'), true)) {
$package = $operation->getOperationType() === 'update' ? $operation->getTargetPackage() : $operation->getPackage(); $package = $operation->getOperationType() === 'update' ? $operation->getTargetPackage() : $operation->getPackage();
if ($package->getType() === 'composer-plugin' && $extra = $package->getExtra() && isset($extra['plugin-modifies-downloads']) && $extra['plugin-modifies-downloads'] === true) { if ($package->getType() === 'composer-plugin' && ($extra = $package->getExtra()) && isset($extra['plugin-modifies-downloads']) && $extra['plugin-modifies-downloads'] === true) {
if ($batch) { if ($batch) {
$batches[] = $batch; $batches[] = $batch;
} }

View File

@ -42,8 +42,28 @@ class TransactionTest extends TestCase
$packageG = $this->getPackage('g/g', '1.0.0'), $packageG = $this->getPackage('g/g', '1.0.0'),
$packageA0first = $this->getPackage('a0/first', '1.2.3'), $packageA0first = $this->getPackage('a0/first', '1.2.3'),
$packageFalias2 = $this->getAliasPackage($packageF, 'dev-bar'), $packageFalias2 = $this->getAliasPackage($packageF, 'dev-bar'),
$plugin = $this->getPackage('x/plugin', '1.0.0'),
$plugin2Dep = $this->getPackage('x/plugin2-dep', '1.0.0'),
$plugin2 = $this->getPackage('x/plugin2', '1.0.0'),
$dlModifyingPlugin = $this->getPackage('x/downloads-modifying', '1.0.0'),
$dlModifyingPlugin2Dep = $this->getPackage('x/downloads-modifying2-dep', '1.0.0'),
$dlModifyingPlugin2 = $this->getPackage('x/downloads-modifying2', '1.0.0'),
); );
$plugin->setType('composer-installer');
foreach (array($plugin2, $dlModifyingPlugin, $dlModifyingPlugin2) as $pluginPackage) {
$pluginPackage->setType('composer-plugin');
}
$plugin2->setRequires(array(
'x/plugin2-dep' => new Link('x/plugin2', 'x/plugin2-dep', $this->getVersionConstraint('=', '1.0.0'), Link::TYPE_REQUIRE),
));
$dlModifyingPlugin2->setRequires(array(
'x/downloads-modifying2-dep' => new Link('x/downloads-modifying2', 'x/downloads-modifying2-dep', $this->getVersionConstraint('=', '1.0.0'), Link::TYPE_REQUIRE),
));
$dlModifyingPlugin->setExtra(array('plugin-modifies-downloads' => true));
$dlModifyingPlugin2->setExtra(array('plugin-modifies-downloads' => true));
$packageD->setRequires(array( $packageD->setRequires(array(
'f/f' => new Link('d/d', 'f/f', $this->getVersionConstraint('>', '0.2'), Link::TYPE_REQUIRE), 'f/f' => new Link('d/d', 'f/f', $this->getVersionConstraint('>', '0.2'), Link::TYPE_REQUIRE),
'g/provider' => new Link('d/d', 'g/provider', $this->getVersionConstraint('>', '0.2'), Link::TYPE_REQUIRE), 'g/provider' => new Link('d/d', 'g/provider', $this->getVersionConstraint('>', '0.2'), Link::TYPE_REQUIRE),
@ -54,6 +74,12 @@ class TransactionTest extends TestCase
array('job' => 'uninstall', 'package' => $packageC), array('job' => 'uninstall', 'package' => $packageC),
array('job' => 'uninstall', 'package' => $packageE), array('job' => 'uninstall', 'package' => $packageE),
array('job' => 'markAliasUninstalled', 'package' => $packageEalias), array('job' => 'markAliasUninstalled', 'package' => $packageEalias),
array('job' => 'install', 'package' => $dlModifyingPlugin),
array('job' => 'install', 'package' => $dlModifyingPlugin2Dep),
array('job' => 'install', 'package' => $dlModifyingPlugin2),
array('job' => 'install', 'package' => $plugin),
array('job' => 'install', 'package' => $plugin2Dep),
array('job' => 'install', 'package' => $plugin2),
array('job' => 'install', 'package' => $packageA0first), array('job' => 'install', 'package' => $packageA0first),
array('job' => 'update', 'from' => $packageB, 'to' => $packageBnew), array('job' => 'update', 'from' => $packageB, 'to' => $packageBnew),
array('job' => 'install', 'package' => $packageG), array('job' => 'install', 'package' => $packageG),