|
12 | 12 |
|
13 | 13 | namespace App\Package; |
14 | 14 |
|
| 15 | +use App\Audit\AbandonmentReason; |
15 | 16 | use App\Entity\ConflictLink; |
16 | 17 | use App\Entity\Dependent; |
17 | 18 | use App\Entity\DevRequireLink; |
@@ -251,7 +252,7 @@ public function update(IOInterface $io, Config $config, Package $package, VcsRep |
251 | 252 | } |
252 | 253 | $processedVersions[strtolower($version->getVersion())] = $version; |
253 | 254 |
|
254 | | - $result = $this->updateInformation($io, $versionRepository, $package, $existingVersions, $version, $flags, $rootIdentifier); |
| 255 | + $result = $this->updateInformation($io, $versionRepository, $package, $existingVersions, $version, $flags, $rootIdentifier, $driver); |
255 | 256 | $versionId = false; |
256 | 257 | if ($result['updated']) { |
257 | 258 | \assert($result['object'] instanceof Version); |
@@ -364,7 +365,7 @@ public function update(IOInterface $io, Config $config, Package $package, VcsRep |
364 | 365 | * |
365 | 366 | * @return array{updated: true, id: int|null, version: string, object: Version}|array{updated: false, id: int|null, version: string, object: null} |
366 | 367 | */ |
367 | | - private function updateInformation(IOInterface $io, VersionRepository $versionRepo, Package $package, array $existingVersions, CompletePackageInterface $data, int $flags, string $rootIdentifier): array |
| 368 | + private function updateInformation(IOInterface $io, VersionRepository $versionRepo, Package $package, array $existingVersions, CompletePackageInterface $data, int $flags, string $rootIdentifier, VcsDriverInterface $driver): array |
368 | 369 | { |
369 | 370 | $em = $this->getEM(); |
370 | 371 | $version = new Version(); |
@@ -427,6 +428,7 @@ private function updateInformation(IOInterface $io, VersionRepository $versionRe |
427 | 428 | $package->setType($this->sanitize($data->getType())); |
428 | 429 | if ($data->isAbandoned() && !$package->isAbandoned()) { |
429 | 430 | $io->write('Marking package abandoned as per composer metadata from '.$version->getVersion()); |
| 431 | + $package->abandonmentReason = $this->detectAbandonmentReason($driver, $rootIdentifier); |
430 | 432 | $package->setAbandoned(true); |
431 | 433 | if ($data->getReplacementPackage()) { |
432 | 434 | $package->setReplacementPackage($data->getReplacementPackage()); |
@@ -845,4 +847,41 @@ private function sanitize(?string $str): ?string |
845 | 847 |
|
846 | 848 | return Preg::replace("{[\x01-\x1A]}u", '', $str); |
847 | 849 | } |
| 850 | + |
| 851 | + private function detectAbandonmentReason(VcsDriverInterface $driver, string $rootIdentifier): AbandonmentReason |
| 852 | + { |
| 853 | + $isArchived = false; |
| 854 | + $composerHasAbandoned = false; |
| 855 | + |
| 856 | + // is repository archived (GitHub or GitLab) |
| 857 | + if ($driver instanceof GitHubDriver || $driver instanceof GitLabDriver) { |
| 858 | + try { |
| 859 | + $repoData = $driver->getRepoData(); |
| 860 | + $isArchived = !empty($repoData['archived']); |
| 861 | + } catch (\Exception $e) { |
| 862 | + // If we can't get repo data, assume not archived |
| 863 | + } |
| 864 | + } |
| 865 | + |
| 866 | + // abandoned field in composer.json explicitly set |
| 867 | + try { |
| 868 | + $composerJson = $driver->getFileContent('composer.json', $rootIdentifier); |
| 869 | + if ($composerJson) { |
| 870 | + $composerData = json_decode($composerJson, true); |
| 871 | + $composerHasAbandoned = isset($composerData['abandoned']); |
| 872 | + } |
| 873 | + } catch (\Exception $e) { |
| 874 | + // composer.json couldn't be read, so the abandoned state couldn't be retrieved |
| 875 | + } |
| 876 | + |
| 877 | + if ($isArchived && $composerHasAbandoned) { |
| 878 | + return AbandonmentReason::Both; |
| 879 | + } elseif ($isArchived) { |
| 880 | + return AbandonmentReason::RepositoryArchived; |
| 881 | + } elseif ($composerHasAbandoned) { |
| 882 | + return AbandonmentReason::ComposerJson; |
| 883 | + } |
| 884 | + |
| 885 | + return AbandonmentReason::Unknown; |
| 886 | + } |
848 | 887 | } |
0 commit comments