Skip to content

Commit a1f723a

Browse files
committed
Add distribution builder
1 parent 55d63a9 commit a1f723a

File tree

5 files changed

+119
-4
lines changed

5 files changed

+119
-4
lines changed

src/DependencyInjection/DirigentConfiguration.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ public function getConfigTreeBuilder(): TreeBuilder
3737
->scalarNode('periodic_update_interval')->defaultValue('P1W')->end()
3838
->end()
3939
->end()
40+
->arrayNode('dist_builder')
41+
->canBeEnabled()
42+
->children()
43+
->booleanNode('dev_packages')->defaultFalse()->end()
44+
->end()
45+
->end()
4046
->arrayNode('dist_mirroring')
4147
->canBeEnabled()
4248
->children()

src/DependencyInjection/DirigentExtension.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ protected function loadInternal(array $mergedConfig, ContainerBuilder $container
3333
$container->setParameter('dirigent.packages.periodic_updates', $mergedConfig['packages']['periodic_updates']);
3434
$container->setParameter('dirigent.packages.periodic_update_interval', $mergedConfig['packages']['periodic_update_interval']);
3535

36+
$container->setParameter('dirigent.dist_builder.enabled', $mergedConfig['dist_builder']['enabled']);
37+
$container->setParameter('dirigent.dist_builder.dev_packages', $mergedConfig['dist_builder']['dev_packages']);
38+
3639
$container->setParameter('dirigent.dist_mirroring.enabled', $mergedConfig['dist_mirroring']['enabled']);
3740
$container->setParameter('dirigent.dist_mirroring.preferred', $mergedConfig['dist_mirroring']['preferred']);
3841
$container->setParameter('dirigent.dist_mirroring.dev_packages', $mergedConfig['dist_mirroring']['dev_packages']);

src/Doctrine/Entity/Version.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace CodedMonkey\Dirigent\Doctrine\Entity;
44

55
use CodedMonkey\Dirigent\Doctrine\Repository\VersionRepository;
6+
use Composer\Package\Package as ComposerPackage;
7+
use Composer\Package\PackageInterface;
68
use Composer\Package\Version\VersionParser;
79
use Composer\Pcre\Preg;
810
use Doctrine\Common\Collections\ArrayCollection;
@@ -512,6 +514,21 @@ public function setReleasedAt(?\DateTimeInterface $releasedAt): void
512514
$this->releasedAt = $releasedAt;
513515
}
514516

517+
public function getSourceReference(): ?string
518+
{
519+
return $this->source['reference'] ?? null;
520+
}
521+
522+
public function getSourceType(): ?string
523+
{
524+
return $this->source['type'] ?? null;
525+
}
526+
527+
public function getSourceUrl(): ?string
528+
{
529+
return $this->source['url'] ?? null;
530+
}
531+
515532
public function getDistReference(): ?string
516533
{
517534
return $this->dist['reference'] ?? null;
@@ -703,6 +720,16 @@ public function toComposerArray(): array
703720
return $data;
704721
}
705722

723+
public function toComposerPackage(): PackageInterface
724+
{
725+
$cp = new ComposerPackage($this->getName(), $this->getNormalizedVersion(), $this->getVersion());
726+
727+
$cp->setSourceReference($this->getSourceReference());
728+
$cp->setSourceUrl($this->getSourceUrl());
729+
730+
return $cp;
731+
}
732+
706733
private function sortAuthorKeys(string $a, string $b): int
707734
{
708735
static $order = ['name' => 1, 'email' => 2, 'homepage' => 3, 'role' => 4];

src/Package/PackageDistributionResolver.php

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,35 @@
33
namespace CodedMonkey\Dirigent\Package;
44

55
use CodedMonkey\Dirigent\Composer\ComposerClient;
6+
use CodedMonkey\Dirigent\Composer\ConfigFactory;
67
use CodedMonkey\Dirigent\Doctrine\Entity\Version;
8+
use Composer\IO\BufferIO;
9+
use Composer\Pcre\Preg;
10+
use Composer\Util\Filesystem as ComposerFilesystem;
11+
use Composer\Util\Git as GitUtility;
12+
use Composer\Util\ProcessExecutor;
13+
use Composer\Util\Url;
714
use Symfony\Component\DependencyInjection\Attribute\Autowire;
815
use Symfony\Component\Filesystem\Filesystem;
916

1017
readonly class PackageDistributionResolver
1118
{
1219
private Filesystem $filesystem;
13-
private string $storagePath;
20+
private string $buildStoragePath;
21+
private string $distributionStoragePath;
1422

1523
public function __construct(
1624
private ComposerClient $composer,
1725
#[Autowire(param: 'dirigent.storage.path')]
1826
string $storagePath,
27+
#[Autowire(param: 'dirigent.dist_builder.enabled')]
28+
private bool $buildDistributions,
29+
#[Autowire(param: 'dirigent.dist_builder.dev_packages')]
30+
private bool $buildDevDistributions,
1931
) {
2032
$this->filesystem = new Filesystem();
21-
$this->storagePath = "$storagePath/distribution";
33+
$this->buildStoragePath = "$storagePath/distribution-builder";
34+
$this->distributionStoragePath = "$storagePath/distribution";
2235
}
2336

2437
public function exists(string $packageName, string $packageVersion, string $reference, string $type): bool
@@ -28,7 +41,7 @@ public function exists(string $packageName, string $packageVersion, string $refe
2841

2942
public function path(string $packageName, string $packageVersion, string $reference, string $type): string
3043
{
31-
return "{$this->storagePath}/{$packageName}/{$packageVersion}-{$reference}.{$type}";
44+
return "$this->distributionStoragePath/$packageName/$packageVersion-$reference.$type";
3245
}
3346

3447
public function resolve(Version $version, string $reference, string $type): bool
@@ -41,7 +54,13 @@ public function resolve(Version $version, string $reference, string $type): bool
4154
return true;
4255
}
4356

44-
if ($reference !== $version->getDistReference() || $type !== $version->getDistType()) {
57+
if (
58+
!$version->getDist()
59+
&& $this->buildDistributions
60+
&& (!$version->isDevelopment() || $this->buildDevDistributions)
61+
) {
62+
return $this->build($version, $reference, $type);
63+
} elseif ($reference !== $version->getDistReference() || $type !== $version->getDistType()) {
4564
return false;
4665
}
4766

@@ -55,4 +74,37 @@ public function resolve(Version $version, string $reference, string $type): bool
5574

5675
return true;
5776
}
77+
78+
private function build(Version $version, string $reference, string $type): bool
79+
{
80+
if ($reference !== $version->getSourceReference() || $type !== 'zip') {
81+
return false;
82+
}
83+
84+
$package = $version->getPackage();
85+
$packageName = $package->getName();
86+
$packageVersion = $version->getNormalizedVersion();
87+
$repositoryUrl = $package->getRepositoryUrl();
88+
$distributionPath = $this->path($packageName, $packageVersion, $reference, $type);
89+
90+
$io = new BufferIO();
91+
$config = ConfigFactory::createForVcsRepository($repositoryUrl, $package->getRepositoryCredentials());
92+
93+
$gitUtility = new GitUtility(
94+
$io,
95+
$config,
96+
$process = new ProcessExecutor($io),
97+
new ComposerFilesystem($process),
98+
);
99+
100+
$cachePath = $config->get('cache-vcs-dir') . '/' . Preg::replace('{[^a-z0-9.]}i', '-', Url::sanitize($repositoryUrl)) . '/';
101+
102+
$this->filesystem->mkdir(dirname($distributionPath));
103+
104+
$gitUtility->runCommands([
105+
['git', 'archive', '--format=zip', "--output=$distributionPath", $reference],
106+
], $repositoryUrl, $cachePath);
107+
108+
return true;
109+
}
58110
}

src/Package/PackageProviderManager.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,28 @@
22

33
namespace CodedMonkey\Dirigent\Package;
44

5+
use CodedMonkey\Dirigent\Composer\ComposerClient;
56
use CodedMonkey\Dirigent\Doctrine\Entity\Package;
67
use Composer\MetadataMinifier\MetadataMinifier;
78
use Symfony\Component\DependencyInjection\Attribute\Autowire;
89
use Symfony\Component\Filesystem\Filesystem;
10+
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
11+
use Symfony\Component\Routing\RouterInterface;
912

1013
readonly class PackageProviderManager
1114
{
1215
private Filesystem $filesystem;
1316
private string $storagePath;
1417

1518
public function __construct(
19+
private ComposerClient $composer,
20+
private RouterInterface $router,
1621
#[Autowire(param: 'dirigent.storage.path')]
1722
string $storagePath,
23+
#[Autowire(param: 'dirigent.dist_builder.enabled')]
24+
private bool $buildDistributions,
25+
#[Autowire(param: 'dirigent.dist_builder.dev_packages')]
26+
private bool $buildDevDistributions,
1827
) {
1928
$this->filesystem = new Filesystem();
2029
$this->storagePath = "$storagePath/provider";
@@ -31,6 +40,24 @@ public function dump(Package $package): void
3140
foreach ($versions as $version) {
3241
$versionData = $version->toComposerArray();
3342

43+
if (
44+
!$version->getDist()
45+
&& $this->buildDistributions
46+
&& (!$version->isDevelopment() || $this->buildDevDistributions)
47+
) {
48+
$versionData['dist'] = [
49+
'type' => 'zip',
50+
'url' => $this->router->generate('api_package_distribution', [
51+
'packageName' => $package->getName(),
52+
'packageVersion' => $version->getNormalizedVersion(),
53+
'reference' => $version->getSourceReference(),
54+
'type' => 'zip',
55+
], UrlGeneratorInterface::ABSOLUTE_URL),
56+
'reference' => $version->getSourceReference(),
57+
'shasum' => '',
58+
];
59+
}
60+
3461
if (!$version->isDevelopment()) {
3562
$releasePackages[] = $versionData;
3663
} else {

0 commit comments

Comments
 (0)