From 696519d5fb4180483e7cdd410d75186ea351e055 Mon Sep 17 00:00:00 2001 From: Tim Goudriaan Date: Mon, 23 Mar 2026 09:53:20 +0100 Subject: [PATCH] Add indices to package version links to maintain the order of the links from the source material --- migrations/Version20260323085126.php | 64 +++++++++++++++++++++ src/Doctrine/Entity/AbstractVersionLink.php | 13 +++++ src/Doctrine/Entity/Version.php | 6 ++ src/Package/PackageMetadataResolver.php | 33 ++++++++--- 4 files changed, 108 insertions(+), 8 deletions(-) create mode 100644 migrations/Version20260323085126.php diff --git a/migrations/Version20260323085126.php b/migrations/Version20260323085126.php new file mode 100644 index 00000000..91bdb69b --- /dev/null +++ b/migrations/Version20260323085126.php @@ -0,0 +1,64 @@ +addSql(<<addSql(<<addSql(<<addSql(<<id; } + public function getIndex(): int + { + return $this->index; + } + + public function setIndex(int $index): void + { + $this->index = $index; + } + public function getVersion(): Version { return $this->version; diff --git a/src/Doctrine/Entity/Version.php b/src/Doctrine/Entity/Version.php index 318f6b38..164a60c9 100644 --- a/src/Doctrine/Entity/Version.php +++ b/src/Doctrine/Entity/Version.php @@ -56,21 +56,27 @@ class Version extends TrackedEntity implements \Stringable private ?array $dist = null; #[ORM\OneToMany(mappedBy: 'version', targetEntity: VersionRequireLink::class, cascade: ['persist', 'detach', 'remove'])] + #[ORM\OrderBy(['index' => 'ASC'])] private Collection $require; #[ORM\OneToMany(mappedBy: 'version', targetEntity: VersionDevRequireLink::class, cascade: ['persist', 'detach', 'remove'])] + #[ORM\OrderBy(['index' => 'ASC'])] private Collection $devRequire; #[ORM\OneToMany(mappedBy: 'version', targetEntity: VersionConflictLink::class, cascade: ['persist', 'detach', 'remove'])] + #[ORM\OrderBy(['index' => 'ASC'])] private Collection $conflict; #[ORM\OneToMany(mappedBy: 'version', targetEntity: VersionProvideLink::class, cascade: ['persist', 'detach', 'remove'])] + #[ORM\OrderBy(['index' => 'ASC'])] private Collection $provide; #[ORM\OneToMany(mappedBy: 'version', targetEntity: VersionReplaceLink::class, cascade: ['persist', 'detach', 'remove'])] + #[ORM\OrderBy(['index' => 'ASC'])] private Collection $replace; #[ORM\OneToMany(mappedBy: 'version', targetEntity: VersionSuggestLink::class, cascade: ['persist', 'detach', 'remove'])] + #[ORM\OrderBy(['index' => 'ASC'])] private Collection $suggest; #[ORM\ManyToMany(targetEntity: Keyword::class, inversedBy: 'versions', cascade: ['persist', 'detach', 'remove'])] diff --git a/src/Package/PackageMetadataResolver.php b/src/Package/PackageMetadataResolver.php index 7ad02e90..0490dadb 100644 --- a/src/Package/PackageMetadataResolver.php +++ b/src/Package/PackageMetadataResolver.php @@ -317,6 +317,7 @@ private function updateVersion(Package $package, Version $version, CompletePacka // handle links foreach (self::SUPPORTED_LINK_TYPES as $linkType => $opts) { $links = []; + $linkIndex = 0; foreach ($data->{$opts['method']}() as $link) { $constraint = $link->getPrettyConstraint(); if (str_contains($constraint, ',') && str_contains($constraint, '@')) { @@ -329,7 +330,7 @@ private function updateVersion(Package $package, Version $version, CompletePacka }, $constraint); } - $links[$link->getTarget()] = $constraint; + $links[$link->getTarget()] = ['constraint' => $constraint, 'index' => $linkIndex++]; } /** @var AbstractVersionLink $link */ @@ -337,20 +338,25 @@ private function updateVersion(Package $package, Version $version, CompletePacka $linkPackageName = $link->getLinkedPackageName(); // Clear links that have changed/disappeared (for updates) - if (!isset($links[$linkPackageName]) || $links[$linkPackageName] !== $link->getLinkedVersionConstraint()) { + if (!isset($links[$linkPackageName]) || $links[$linkPackageName]['constraint'] !== $link->getLinkedVersionConstraint()) { $version->{'get' . $linkType}()->removeElement($link); $em->remove($link); } else { + // Update index if it changed + if ($link->getIndex() !== $links[$linkPackageName]['index']) { + $link->setIndex($links[$linkPackageName]['index']); + } // Clear those that are already set unset($links[$linkPackageName]); } } - foreach ($links as $linkPackageName => $linkPackageConstraint) { + foreach ($links as $linkPackageName => $linkData) { /** @var AbstractVersionLink $link */ $link = new $opts['entity'](); $link->setLinkedPackageName($linkPackageName); - $link->setLinkedVersionConstraint($linkPackageConstraint); + $link->setLinkedVersionConstraint($linkData['constraint']); + $link->setIndex($linkData['index']); $version->{'add' . $linkType . 'Link'}($link); $link->setVersion($version); $em->persist($link); @@ -358,23 +364,34 @@ private function updateVersion(Package $package, Version $version, CompletePacka } // handle suggests - if ($suggests = $data->getSuggests()) { + if ($suggestsData = $data->getSuggests()) { + $suggests = []; + $suggestIndex = 0; + foreach ($suggestsData as $suggestPackageName => $suggestConstraint) { + $suggests[$suggestPackageName] = ['constraint' => $suggestConstraint, 'index' => $suggestIndex++]; + } + foreach ($version->getSuggest() as $link) { $linkPackageName = $link->getLinkedPackageName(); // clear links that have changed/disappeared (for updates) - if (!isset($suggests[$linkPackageName]) || $suggests[$linkPackageName] !== $link->getLinkedVersionConstraint()) { + if (!isset($suggests[$linkPackageName]) || $suggests[$linkPackageName]['constraint'] !== $link->getLinkedVersionConstraint()) { $version->getSuggest()->removeElement($link); $em->remove($link); } else { + // Update index if it changed + if ($link->getIndex() !== $suggests[$linkPackageName]['index']) { + $link->setIndex($suggests[$linkPackageName]['index']); + } // clear those that are already set unset($suggests[$linkPackageName]); } } - foreach ($suggests as $linkPackageName => $linkPackageConstraint) { + foreach ($suggests as $linkPackageName => $linkData) { $link = new VersionSuggestLink(); $link->setLinkedPackageName($linkPackageName); - $link->setLinkedVersionConstraint($linkPackageConstraint); + $link->setLinkedVersionConstraint($linkData['constraint']); + $link->setIndex($linkData['index']); $version->addSuggestLink($link); $link->setVersion($version); $em->persist($link);