Skip to content

Commit

Permalink
Prevent auto-unlocked path repo packages from also unlocking their tr…
Browse files Browse the repository at this point in the history
…ansitive deps when -w/-W is used
  • Loading branch information
Seldaek committed Oct 14, 2021
1 parent 79727d3 commit fcdf013
Showing 1 changed file with 24 additions and 13 deletions.
37 changes: 24 additions & 13 deletions src/Composer/DependencyResolver/PoolBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,16 @@ class PoolBuilder
/** @var array<string, string> */
private $skippedLoad = array();

/**
* Keeps a list of dependencies which are locked but were auto-unlocked as they are path repositories
*
* This half-unlocked state means the package itself will update but the UPDATE_LISTED_WITH_TRANSITIVE_DEPS*
* flags will not apply until the package really gets unlocked in some other way than being a path repo
*
* @var array<string, true>
*/
private $pathRepoUnlocked = array();

/**
* Keeps a list of dependencies which are root requirements, and as such
* have already their maximum required range loaded and can not be
Expand Down Expand Up @@ -147,6 +157,17 @@ public function buildPool(array $repositories, Request $request)

foreach ($request->getLockedRepository()->getPackages() as $lockedPackage) {
if (!$this->isUpdateAllowed($lockedPackage)) {
// Path repo packages are never loaded from lock, to force them to always remain in sync
// unless symlinking is disabled in which case we probably should rather treat them like
// regular packages
if ($lockedPackage->getDistType() === 'path') {
$transportOptions = $lockedPackage->getTransportOptions();
if (!isset($transportOptions['symlink']) || $transportOptions['symlink'] !== false) {
$this->pathRepoUnlocked[$lockedPackage->getName()] = true;
continue;
}
}

$request->lockPackage($lockedPackage);
$lockedName = $lockedPackage->getName();
// remember which packages we skipped loading remote content for in this partial update
Expand Down Expand Up @@ -343,12 +364,12 @@ private function loadPackagesMarkedForLoading(Request $request, $repositories)
}
foreach ($result['packages'] as $package) {
$this->loadedPerRepo[$repoIndex][$package->getName()][$package->getVersion()] = $package;
$this->loadPackage($request, $package);
$this->loadPackage($request, $package, !isset($this->pathRepoUnlocked[$package->getName()]));
}
}
}

private function loadPackage(Request $request, BasePackage $package, $propagateUpdate = true)
private function loadPackage(Request $request, BasePackage $package, $propagateUpdate)
{
$index = $this->indexCounter++;
$this->packages[$index] = $package;
Expand Down Expand Up @@ -449,16 +470,6 @@ private function isRootRequire(Request $request, $name)
*/
private function isUpdateAllowed(PackageInterface $package)
{
// Path repo packages are never loaded from lock, to force them to always remain in sync
// unless symlinking is disabled in which case we probably should rather treat them like
// regular packages
if ($package->getDistType() === 'path') {
$transportOptions = $package->getTransportOptions();
if (!isset($transportOptions['symlink']) || $transportOptions['symlink'] !== false) {
return true;
}
}

foreach ($this->updateAllowList as $pattern => $void) {
$patternRegexp = BasePackage::packageNameToRegexp($pattern);
if (preg_match($patternRegexp, $package->getName())) {
Expand Down Expand Up @@ -508,7 +519,7 @@ private function unlockPackage(Request $request, $name)
$this->unlockPackage($request, $this->skippedLoad[$name]);
}

unset($this->skippedLoad[$name], $this->loadedPackages[$name], $this->maxExtendedReqs[$name]);
unset($this->skippedLoad[$name], $this->loadedPackages[$name], $this->maxExtendedReqs[$name], $this->pathRepoUnlocked[$name]);

// remove locked package by this name which was already initialized
foreach ($request->getLockedPackages() as $lockedPackage) {
Expand Down

0 comments on commit fcdf013

Please sign in to comment.