Skip to content

Commit

Permalink
Refactor dumping of provider files with custom logic
Browse files Browse the repository at this point in the history
  • Loading branch information
codedmonkey committed Aug 23, 2024
1 parent 0f6446b commit e69b494
Show file tree
Hide file tree
Showing 7 changed files with 230 additions and 15 deletions.
13 changes: 13 additions & 0 deletions src/Doctrine/Entity/Package.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ class Package
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $description = null;

#[ORM\Column(nullable: true)]
private ?string $type = null;

#[ORM\Column(nullable: true)]
private ?string $language = null;

Expand Down Expand Up @@ -146,6 +149,16 @@ public function setDescription(?string $description): void
$this->description = $description;
}

public function getType(): ?string
{
return $this->type;
}

public function setType(?string $type): void
{
$this->type = $type;
}

public function getLanguage(): ?string
{
return $this->language;
Expand Down
8 changes: 8 additions & 0 deletions src/Doctrine/Entity/PackageLink.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,12 @@ public function setVersion(Version $version): void
{
$this->version = $version;
}

/**
* @return non-empty-array<string, string>
*/
public function toArray(): array
{
return [$this->getPackageName() => $this->getPackageVersion()];
}
}
133 changes: 132 additions & 1 deletion src/Doctrine/Entity/Version.php
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ public function setPhpExt(?array $phpExt): void

public function getAuthors(): array
{
return $this->authors;
return $this->authors ?? [];
}

public function setAuthors(array $authors): void
Expand Down Expand Up @@ -536,4 +536,135 @@ public function getVersionAlias(): string

return '';
}

/**
* Get funding, sorted to help the V2 metadata compression algo
* @return array<array{type?: string, url?: string}>|null
*/
public function getFundingSorted(): ?array
{
if ($this->funding === null) {
return null;
}

$funding = $this->funding;
usort($funding, static function ($a, $b) {
$keyA = ($a['type'] ?? '') . ($a['url'] ?? '');
$keyB = ($b['type'] ?? '') . ($b['url'] ?? '');

return $keyA <=> $keyB;
});

return $funding;
}

public function toComposerArray(): array
{
$tags = [];
foreach ($this->getTags() as $tag) {
$tags[] = $tag->getName();
}

$authors = $this->getAuthors();
foreach ($authors as &$author) {
uksort($author, [$this, 'sortAuthorKeys']);
}
unset($author);

$data = [
'name' => $this->getName(),
'description' => (string) $this->getDescription(),
'keywords' => $tags,
'homepage' => (string) $this->getHomepage(),
'version' => $this->getVersion(),
'version_normalized' => $this->getNormalizedVersion(),
'license' => $this->getLicense(),
'authors' => $authors,
'source' => $this->getSource(),
'dist' => $this->getDist(),
'type' => $this->getType(),
];

if ($this->getSupport()) {
$data['support'] = $this->getSupport();
}
if ($this->getPhpExt() !== null) {
$data['php-ext'] = $this->getPhpExt();
}
$funding = $this->getFundingSorted();
if ($funding !== null) {
$data['funding'] = $funding;
}
if ($this->getReleasedAt()) {
$data['time'] = $this->getReleasedAt()->format('Y-m-d\TH:i:sP');
}
if ($this->getAutoload()) {
$data['autoload'] = $this->getAutoload();
}
if ($this->getExtra()) {
$data['extra'] = $this->getExtra();
}
if ($this->getTargetDir()) {
$data['target-dir'] = $this->getTargetDir();
}
if ($this->getIncludePaths()) {
$data['include-path'] = $this->getIncludePaths();
}
if ($this->getBinaries()) {
$data['bin'] = $this->getBinaries();
}

$supportedLinkTypes = [
'require' => 'require',
'devRequire' => 'require-dev',
'suggest' => 'suggest',
'conflict' => 'conflict',
'provide' => 'provide',
'replace' => 'replace',
];

if ($this->isDefaultBranch()) {
$data['default-branch'] = true;
}

foreach ($supportedLinkTypes as $method => $linkType) {
if (isset($versionData[$this->id][$method])) {
foreach ($versionData[$this->id][$method] as $link) {
$data[$linkType][$link['name']] = $link['version'];
}
continue;
}
/** @var PackageLink $link */
foreach ($this->{'get'.$method}() as $link) {
$link = $link->toArray();
$data[$linkType][key($link)] = current($link);
}
}

if ($this->getPackage()->isAbandoned()) {
$data['abandoned'] = $this->getPackage()->getReplacementPackage() ?: true;
}

if (isset($data['support'])) {
ksort($data['support']);
}

if (isset($data['php-ext']['configure-options'])) {
usort($data['php-ext']['configure-options'], fn ($a, $b) => $a['name'] ?? '' <=> $b['name'] ?? '');
}

return $data;
}

private function sortAuthorKeys(string $a, string $b): int
{
static $order = ['name' => 1, 'email' => 2, 'homepage' => 3, 'role' => 4];
$aIndex = $order[$a] ?? 5;
$bIndex = $order[$b] ?? 5;
if ($aIndex === $bIndex) {
return $a <=> $b;
}

return $aIndex <=> $bIndex;
}
}
11 changes: 11 additions & 0 deletions src/Message/DumpPackageProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace CodedMonkey\Conductor\Message;

readonly class DumpPackageProvider
{
public function __construct(
public int $packageId,
) {
}
}
24 changes: 24 additions & 0 deletions src/Message/DumpPackageProviderHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace CodedMonkey\Conductor\Message;

use CodedMonkey\Conductor\Doctrine\Repository\PackageRepository;
use CodedMonkey\Conductor\Package\PackageProviderManager;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;

#[AsMessageHandler]
readonly class DumpPackageProviderHandler
{
public function __construct(
private PackageRepository $packageRepository,
private PackageProviderManager $providerManager,
) {
}

public function __invoke(DumpPackageProvider $message): void
{
$package = $this->packageRepository->find($message->packageId);

$this->providerManager->dump($package);
}
}
35 changes: 31 additions & 4 deletions src/Package/PackageMetadataResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use CodedMonkey\Conductor\Doctrine\Entity\Version;
use CodedMonkey\Conductor\Doctrine\Repository\RegistryRepository;
use CodedMonkey\Conductor\Doctrine\Repository\VersionRepository;
use CodedMonkey\Conductor\Message\DumpPackageProvider;
use Composer\IO\NullIO;
use Composer\Package\AliasPackage;
use Composer\Package\CompletePackageInterface;
Expand All @@ -20,6 +21,7 @@
use Composer\Repository\VcsRepository;
use Composer\Util\HttpDownloader;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Messenger\MessageBusInterface;

class PackageMetadataResolver
{
Expand Down Expand Up @@ -47,7 +49,7 @@ class PackageMetadataResolver
];

public function __construct(
private readonly PackageProviderManager $providerManager,
private readonly MessageBusInterface $messenger,
private readonly EntityManagerInterface $entityManager,
private readonly RegistryRepository $registryRepository,
private readonly VersionRepository $versionRepository,
Expand All @@ -70,7 +72,7 @@ public function resolve(Package $package): void

$this->updatePackage($package, $composerPackages);

$this->providerManager->dump($package, $composerPackages);
$this->messenger->dispatch(new DumpPackageProvider($package->getId()));
}

public function findPackageProvider(string $packageName): ?Registry
Expand Down Expand Up @@ -177,14 +179,39 @@ private function updateVersion(Package $package, Version $version, CompletePacka
$version->setIncludePaths($data->getIncludePaths());
$version->setSupport($data->getSupport());
$version->setFunding($data->getFunding());

$version->setHomepage($data->getHomepage());
$version->setLicense($data->getLicense() ?: []);
$version->setType($this->sanitize($data->getType()));

$version->setPackage($package);
$version->setUpdatedAt(new \DateTime());
$version->setReleasedAt($data->getReleaseDate());

$version->setAuthors([]);
if ($data->getAuthors()) {
$authors = [];
foreach ($data->getAuthors() as $authorData) {
$author = [];

foreach (['email', 'name', 'homepage', 'role'] as $field) {
if (isset($authorData[$field])) {
$author[$field] = trim($authorData[$field]);
if ('' === $author[$field]) {
unset($author[$field]);
}
}
}

// skip authors with no information
if (!isset($authorData['email']) && !isset($authorData['name'])) {
continue;
}

$authors[] = $author;
}
$version->setAuthors($authors);
}

if ($data->getSourceType()) {
$source['type'] = $data->getSourceType();
$source['url'] = $data->getSourceUrl();
Expand All @@ -210,7 +237,7 @@ private function updateVersion(Package $package, Version $version, CompletePacka

if ($data->isDefaultBranch()) {
$package->setDescription($description);
$package->setRepositoryType($this->sanitize($data->getType()));
$package->setType($this->sanitize($data->getType()));
if ($data->isAbandoned() && !$package->isAbandoned()) {
//$io->write('Marking package abandoned as per composer metadata from '.$version->getVersion());
$package->setAbandoned(true);
Expand Down
21 changes: 11 additions & 10 deletions src/Package/PackageProviderManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

use CodedMonkey\Conductor\Doctrine\Entity\Package;
use Composer\MetadataMinifier\MetadataMinifier;
use Composer\Package\Dumper\ArrayDumper;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\Filesystem\Filesystem;

Expand All @@ -21,16 +20,21 @@ public function __construct(
$this->storagePath = "$storagePath/provider";
}

public function dump(Package $package, array $composerPackages): void
public function dump(Package $package): void
{
$releasePackages = [];
$devPackages = [];

foreach ($composerPackages as $composerPackage) {
if (!$composerPackage->isDev()) {
$releasePackages[] = $composerPackage;
$versions = $package->getVersions()->toArray();
usort($versions, [Package::class, 'sortVersions']);

foreach ($versions as $version) {
$versionData = $version->toComposerArray();

if (!$version->isDevelopment()) {
$releasePackages[] = $versionData;
} else {
$devPackages[] = $composerPackage;
$devPackages[] = $versionData;
}
}

Expand All @@ -52,7 +56,6 @@ public function path(string $packageName): string

private function write(string $packageName, array $composerPackages, bool $development = false): void
{

$path = $this->path(!$development ? $packageName : "{$packageName}~dev");
$data = $this->compile($packageName, $composerPackages);

Expand All @@ -65,12 +68,10 @@ private function write(string $packageName, array $composerPackages, bool $devel

private function compile(string $packageName, array $composerPackages): array
{
$data = array_map([new ArrayDumper(), 'dump'], $composerPackages);

return [
'minified' => 'composer/2.0',
'packages' => [
$packageName => MetadataMinifier::minify($data),
$packageName => MetadataMinifier::minify($composerPackages),
],
];
}
Expand Down

0 comments on commit e69b494

Please sign in to comment.