Skip to content

Commit

Permalink
Fix update --lock to avoid updating all metadata except dist/source u…
Browse files Browse the repository at this point in the history
…rls and mirrors (#11850)

We now update the existing package instead of reverting changes in the updated package to ensure we keep all metadata intact, fixes #11787

Co-authored-by: Jordi Boggiano <j.boggiano@seld.be>
  • Loading branch information
drupol and Seldaek committed Mar 5, 2024
1 parent 1dc2c93 commit 66acb84
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 28 deletions.
83 changes: 59 additions & 24 deletions src/Composer/DependencyResolver/LockTransaction.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,36 +104,71 @@ public function getNewLockPackages(bool $devMode, bool $updateMirrors = false):
{
$packages = [];
foreach ($this->resultPackages[$devMode ? 'dev' : 'non-dev'] as $package) {
if (!$package instanceof AliasPackage) {
// if we're just updating mirrors we need to reset references to the same as currently "present" packages' references to keep the lock file as-is
// we do not reset references if the currently present package didn't have any, or if the type of VCS has changed
if ($updateMirrors && !isset($this->presentMap[spl_object_hash($package)])) {
foreach ($this->presentMap as $presentPackage) {
if ($package->getName() === $presentPackage->getName() && $package->getVersion() === $presentPackage->getVersion()) {
if ($presentPackage->getSourceReference() && $presentPackage->getSourceType() === $package->getSourceType()) {
$package->setSourceDistReferences($presentPackage->getSourceReference());
// if the dist url is not one of those handled gracefully by setSourceDistReferences then we should overwrite it with the old one
if ($package->getDistUrl() !== null && !Preg::isMatch('{^https?://(?:(?:www\.)?bitbucket\.org|(api\.)?github\.com|(?:www\.)?gitlab\.com)/}i', $package->getDistUrl())) {
$package->setDistUrl($presentPackage->getDistUrl());
}
$package->setDistType($presentPackage->getDistType());
if ($package instanceof Package) {
$package->setDistSha1Checksum($presentPackage->getDistSha1Checksum());
}
}
if ($presentPackage->getReleaseDate() !== null && $package instanceof Package) {
$package->setReleaseDate($presentPackage->getReleaseDate());
}
}
}
}
$packages[] = $package;
if ($package instanceof AliasPackage) {
continue;
}

// if we're just updating mirrors we need to reset everything to the same as currently "present" packages' references to keep the lock file as-is
if ($updateMirrors === true && !array_key_exists(spl_object_hash($package), $this->presentMap)) {
$package = $this->updateMirrorAndUrls($package);
}

$packages[] = $package;
}

return $packages;
}

/**
* Try to return the original package from presentMap with updated URLs/mirrors
*
* If the type of source/dist changed, then we do not update those and keep them as they were
*/
private function updateMirrorAndUrls(BasePackage $package): BasePackage
{
foreach ($this->presentMap as $presentPackage) {
if ($package->getName() !== $presentPackage->getName()) {
continue;
}

if ($package->getVersion() !== $presentPackage->getVersion()) {
continue;
}

if ($presentPackage->getSourceReference() === null) {
continue;
}

if ($presentPackage->getSourceType() !== $package->getSourceType()) {
continue;
}

if ($presentPackage instanceof Package) {
$presentPackage->setSourceUrl($package->getSourceUrl());
$presentPackage->setSourceMirrors($package->getSourceMirrors());
}

// if the dist type changed, we only update the source url/mirrors
if ($presentPackage->getDistType() !== $package->getDistType()) {
return $presentPackage;
}

// update dist url if it is in a known format
if (
$package->getDistUrl() !== null
&& $presentPackage->getDistReference() !== null
&& Preg::isMatch('{^https?://(?:(?:www\.)?bitbucket\.org|(api\.)?github\.com|(?:www\.)?gitlab\.com)/}i', $package->getDistUrl())
) {
$presentPackage->setDistUrl(Preg::replace('{(?<=/|sha=)[a-f0-9]{40}(?=/|$)}i', $presentPackage->getDistReference(), $package->getDistUrl()));
}
$presentPackage->setDistMirrors($package->getDistMirrors());

return $presentPackage;
}

return $package;
}

/**
* Checks which of the given aliases from composer.json are actually in use for the lock file
* @param list<array{package: string, version: string, alias: string, alias_normalized: string}> $aliases
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ g/g is dev and installed in a different ref than the #ref, so it gets updated an
"package": [
{
"name": "a/a", "version": "dev-master",
"source": { "reference": "2222222222222222222222222222222222222222", "url": "https://github.com/a/newa", "type": "git" },
"dist": { "reference": "2222222222222222222222222222222222222222", "url": "https://api.github.com/repos/a/newa/zipball/2222222222222222222222222222222222222222", "type": "zip" },
"require": { "b/b": "^2.0.1" },
"source": { "reference": "2222222222222222222222222222222222222222", "url": "https://github.com/a/newa", "type": "git", "mirrors": [{"url": "https://example.org/src/%package%/%version%/r%reference%.%type%", "preferred": true}] },
"dist": { "reference": "2222222222222222222222222222222222222222", "url": "https://api.github.com/repos/a/newa/zipball/2222222222222222222222222222222222222222", "type": "zip", "mirrors": [{"url": "https://example.org/dists/%package%/%version%/r%reference%.%type%", "preferred": true}] },
"time": "2021-03-27T14:32:16+00:00"
},
{
Expand Down Expand Up @@ -67,6 +68,7 @@ g/g is dev and installed in a different ref than the #ref, so it gets updated an
[
{
"name": "a/a", "version": "dev-master",
"require": { "b/b": "^2" },
"source": { "reference": "1111111111111111111111111111111111111111", "url": "https://github.com/a/a", "type": "git" },
"dist": { "reference": "1111111111111111111111111111111111111111", "url": "https://api.github.com/repos/a/a/zipball/1111111111111111111111111111111111111111", "type": "zip" },
"time": "2021-03-14T16:24:37+00:00"
Expand Down Expand Up @@ -102,6 +104,7 @@ g/g is dev and installed in a different ref than the #ref, so it gets updated an
"packages": [
{
"name": "a/a", "version": "dev-master",
"require": { "b/b": "^2" },
"source": { "reference": "1111111111111111111111111111111111111111", "url": "https://github.com/a/a", "type": "git" },
"dist": { "reference": "1111111111111111111111111111111111111111", "url": "https://api.github.com/repos/a/a/zipball/1111111111111111111111111111111111111111", "type": "zip" },
"time": "2021-03-14T16:24:37+00:00",
Expand Down Expand Up @@ -152,8 +155,9 @@ g/g is dev and installed in a different ref than the #ref, so it gets updated an
"packages": [
{
"name": "a/a", "version": "dev-master",
"source": { "reference": "1111111111111111111111111111111111111111", "url": "https://github.com/a/newa", "type": "git" },
"dist": { "reference": "1111111111111111111111111111111111111111", "url": "https://api.github.com/repos/a/newa/zipball/1111111111111111111111111111111111111111", "type": "zip" },
"require": { "b/b": "^2" },
"source": { "reference": "1111111111111111111111111111111111111111", "url": "https://github.com/a/newa", "type": "git", "mirrors": [{"url": "https://example.org/src/%package%/%version%/r%reference%.%type%", "preferred": true}] },
"dist": { "reference": "1111111111111111111111111111111111111111", "url": "https://api.github.com/repos/a/newa/zipball/1111111111111111111111111111111111111111", "type": "zip", "mirrors": [{"url": "https://example.org/dists/%package%/%version%/r%reference%.%type%", "preferred": true}] },
"time": "2021-03-14T16:24:37+00:00",
"type": "library"
},
Expand Down

0 comments on commit 66acb84

Please sign in to comment.