Consider the following situation:
- Package com.example.foo is installed in version 1.0.0.
- Version 1.0.1 can be upgraded from 1.0.0.
- Version 1.0.2 can be upgraded from 1.0.1 and adds a dependency on
com.woltlab.bar which is not yet installed.
- Version 1.0.3 can be upgraded from 1.0.2.
Now the PackageinstallationScheduler will build the following plan when it's
desired to upgrade com.woltlab.foo from 1.0.0 to 1.0.2:
- Upgrade com.woltlab.foo to 1.0.1
- Install com.woltlab.bar to satisfy the dependencies for 1.0.2
- Upgrade com.woltlab.foo to 1.0.2
- Upgrade com.woltlab.foo to 1.0.3
Now when build the nodes for this plan, the upgrade instructions for 1.0.2 will
not be detected, as the "previous package" logic used for iterative upgrades
will set the previous package of com.woltlab.foo in 1.0.2 to com.woltlab.bar.
Thus when upgrading to 1.0.2 the node builder will believe that com.woltlab.foo
is installed in 1.0.0 when it actually is already upgraded to 1.0.1.
Fix this by leveraging the $pendingPackages list which is already kept up to
date for dependency resolution.
$installation = new PackageInstallationDispatcher($queue);
// work-around for iterative package updates
- if ($this->installation->queue->action == 'update' && $queue->package == $this->installation->queue->package) {
+ if (isset(self::$pendingPackages[$queue->package])) {
$installation->setPreviousPackage([
- 'package' => $this->installation->getArchive()->getPackageInfo('name'),
- 'packageVersion' => $this->installation->getArchive()->getPackageInfo('version'),
+ 'package' => $queue->package,
+ 'packageVersion' => self::$pendingPackages[$queue->package],
]);
}