FestinHegre/vendor/symfony/asset-mapper/ImportMap/ImportMapUpdateChecker.php
2024-09-26 17:26:04 +02:00

94 lines
3.5 KiB
PHP

<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\AssetMapper\ImportMap;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class ImportMapUpdateChecker
{
private const URL_PACKAGE_METADATA = 'https://registry.npmjs.org/%s';
public function __construct(
private readonly ImportMapConfigReader $importMapConfigReader,
private readonly HttpClientInterface $httpClient,
) {
}
/**
* @param string[] $packages
*
* @return PackageUpdateInfo[]
*/
public function getAvailableUpdates(array $packages = []): array
{
$entries = $this->importMapConfigReader->getEntries();
$updateInfos = [];
$responses = [];
foreach ($entries as $entry) {
if (!$entry->isRemotePackage()) {
continue;
}
if ($packages
&& !\in_array($entry->getPackageName(), $packages, true)
&& !\in_array($entry->importName, $packages, true)
) {
continue;
}
$responses[$entry->importName] = $this->httpClient->request('GET', sprintf(self::URL_PACKAGE_METADATA, $entry->getPackageName()), ['headers' => ['Accept' => 'application/vnd.npm.install-v1+json']]);
}
foreach ($responses as $importName => $response) {
$entry = $entries->get($importName);
if (200 !== $response->getStatusCode()) {
throw new \RuntimeException(sprintf('Unable to get latest version for package "%s".', $entry->getPackageName()));
}
$updateInfo = new PackageUpdateInfo($entry->getPackageName(), $entry->version);
try {
$updateInfo->latestVersion = json_decode($response->getContent(), true)['dist-tags']['latest'];
$updateInfo->updateType = $this->getUpdateType($updateInfo->currentVersion, $updateInfo->latestVersion);
} catch (\Exception $e) {
throw new \RuntimeException(sprintf('Unable to get latest version for package "%s".', $entry->getPackageName()), 0, $e);
}
$updateInfos[$importName] = $updateInfo;
}
return $updateInfos;
}
private function getVersionPart(string $version, int $part): ?string
{
return explode('.', $version)[$part] ?? $version;
}
private function getUpdateType(string $currentVersion, string $latestVersion): string
{
if (version_compare($currentVersion, $latestVersion, '>')) {
return PackageUpdateInfo::UPDATE_TYPE_DOWNGRADE;
}
if (version_compare($currentVersion, $latestVersion, '==')) {
return PackageUpdateInfo::UPDATE_TYPE_UP_TO_DATE;
}
if ($this->getVersionPart($currentVersion, 0) < $this->getVersionPart($latestVersion, 0)) {
return PackageUpdateInfo::UPDATE_TYPE_MAJOR;
}
if ($this->getVersionPart($currentVersion, 1) < $this->getVersionPart($latestVersion, 1)) {
return PackageUpdateInfo::UPDATE_TYPE_MINOR;
}
if ($this->getVersionPart($currentVersion, 2) < $this->getVersionPart($latestVersion, 2)) {
return PackageUpdateInfo::UPDATE_TYPE_PATCH;
}
throw new \LogicException(sprintf('Unable to determine update type for "%s" and "%s".', $currentVersion, $latestVersion));
}
}