Skip to content

Commit cee694c

Browse files
committed
Refactor distribution configuration
Signed-off-by: Tim Goudriaan <tim@codedmonkey.com> # Conflicts: # src/DependencyInjection/DirigentConfiguration.php # src/DependencyInjection/DirigentExtension.php # src/Message/UpdatePackageHandler.php
1 parent 6a8ef92 commit cee694c

11 files changed

Lines changed: 144 additions & 66 deletions

docs/configuration-reference.md

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,13 @@ dirigent:
2929
dynamic_update_delay: 'PT4H'
3030
periodic_updates: true
3131
periodic_update_interval: 'P1W'
32-
dist_mirroring:
32+
distributions:
3333
enabled: false
34-
preferred: true
34+
build: true
35+
mirror: false
36+
async_api_requests: false
3537
dev_packages: false
38+
preferred_mirror: true
3639
metadata:
3740
mirror_vcs_repositories: false
3841
```
@@ -109,18 +112,28 @@ The time between periodic updates being scheduled, defaults to once a week.
109112

110113
The time must be defined in the [ISO 8601 durations][iso-8601-durations] format.
111114

112-
## dist_mirroring
115+
## distributions
113116

114117
### enabled
115118

116119
Type: `boolean` | Default: `false`
117120

118-
Whether to enable or disable distribution mirroring
121+
Enable hosting of package distributions.
119122

120-
### preferred
123+
### build
124+
125+
Type: `boolean` | Default: `true`
126+
127+
Enable building distribution from the source.
128+
129+
### mirror
130+
131+
### async_api_requests
121132

122133
### dev_packages
123134

135+
### preferred_mirror
136+
124137
## metadata
125138

126139
### mirror_vcs_repositories

docs/dist-mirroring.md

Lines changed: 0 additions & 15 deletions
This file was deleted.

docs/distributions.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
sidebar_position: 31
3+
---
4+
5+
# Distributions
6+
7+
:::note
8+
9+
This page is a stub.
10+
11+
:::
12+
13+
Dirigent mirrors distributions from their original source if it's provided by the package, or builds the distribution
14+
from the source code.

docs/readme.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@ sidebar_position: 1
88
- [Introduction](introduction.md)
99
- [Installation](installation/readme.md)
1010
- [Getting Started](getting-started.md)
11+
12+
---
13+
1114
- [Automatic Package Updates](automatic-package-updates.md)
12-
- [Dist Mirroring](dist-mirroring.md)
15+
- [Distributions](distributions.md)
1316

1417
---
1518

src/Controller/ApiController.php

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public function root(RouterInterface $router): JsonResponse
6060
'notify-batch' => $router->generate('api_track_installations'),
6161
];
6262

63-
if ($this->getParameter('dirigent.dist_mirroring.enabled')) {
63+
if ($this->getParameter('dirigent.distributions.mirror')) {
6464
$distributionUrlPattern = u($router->getRouteCollection()->get('api_package_distribution')->getPath())
6565
->replace('{package}', '%package%')
6666
->replace('{version}', '%version%')
@@ -70,7 +70,7 @@ public function root(RouterInterface $router): JsonResponse
7070

7171
$data['mirrors'] = [[
7272
'dist-url' => $distributionUrlPattern,
73-
'preferred' => $this->getParameter('dirigent.dist_mirroring.preferred'),
73+
'preferred' => $this->getParameter('dirigent.distributions.preferred_mirror'),
7474
]];
7575
}
7676

@@ -116,7 +116,7 @@ public function packageMetadata(Request $request): Response
116116
#[IsGrantedAccess]
117117
public function packageDistribution(Request $request, string $reference, string $type): Response
118118
{
119-
if (!$this->getParameter('dirigent.dist_mirroring.enabled')) {
119+
if (!$this->getParameter('dirigent.distributions.enabled')) {
120120
throw $this->createNotFoundException();
121121
}
122122

@@ -132,11 +132,7 @@ public function packageDistribution(Request $request, string $reference, string
132132
throw $this->createNotFoundException();
133133
}
134134

135-
if ($version->isDevelopment() && !$this->getParameter('dirigent.dist_mirroring.dev_packages')) {
136-
throw $this->createNotFoundException();
137-
}
138-
139-
if (!$this->distributionResolver->resolve($version, $reference, $type)) {
135+
if (!$this->distributionResolver->resolve($version, $reference, $type, async: $this->getParameter('dirigent.distributions.async_api_requests'))) {
140136
throw $this->createNotFoundException();
141137
}
142138
}

src/DependencyInjection/DirigentConfiguration.php

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -68,27 +68,30 @@ public function getConfigTreeBuilder(): TreeBuilder
6868
->children()
6969
->scalarNode('path')->defaultValue('%kernel.project_dir%/storage')->end()
7070
->end()
71-
->end()
72-
->arrayNode('dist_builder')
73-
->canBeEnabled()
74-
->children()
75-
->booleanNode('dev_packages')->defaultFalse()->end()
76-
->end()
77-
->end()
78-
->arrayNode('dist_mirroring')
79-
->canBeEnabled()
80-
->children()
81-
->booleanNode('preferred')->defaultTrue()->end()
82-
->booleanNode('dev_packages')->defaultFalse()->end()
83-
->end()
8471
->end();
8572

73+
$this->addDistributionsSection($rootNode);
8674
$this->addMetadataSection($rootNode);
8775
$this->addPackagesSection($rootNode);
8876

8977
return $treeBuilder;
9078
}
9179

80+
private function addDistributionsSection(ArrayNodeDefinition|NodeDefinition $rootNode): void
81+
{
82+
$rootNode->children()
83+
->arrayNode('distributions')
84+
->canBeEnabled('Host the distributions of packages')
85+
->children()
86+
->booleanNode('build')->defaultTrue()->info('Build distributions from the source code (if not already provided)')->end()
87+
->booleanNode('mirror')->defaultFalse()->info('Mirror distributions from the original source (if provided)')->end()
88+
->booleanNode('async_api_requests')->defaultFalse()->info('Fetch distributions asynchronously instead of during execution (from the API)')->end()
89+
->booleanNode('dev_versions')->defaultFalse()->info('Include distributions of development versions')->end()
90+
->booleanNode('preferred_mirror')->defaultFalse()->info('Force Composer to download distributions from this registry first')->end()
91+
->end()
92+
->end();
93+
}
94+
9295
private function addMetadataSection(ArrayNodeDefinition|NodeDefinition $rootNode): void
9396
{
9497
$rootNode->children()

src/DependencyInjection/DirigentExtension.php

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ protected function loadInternal(array $mergedConfig, ContainerBuilder $container
1717
$container->setParameter('dirigent.title', $mergedConfig['title']);
1818
$container->setParameter('dirigent.slug', $slug);
1919

20+
$this->registerDistributionsConfiguration($mergedConfig['distributions'], $container);
2021
$this->registerEncryptionConfiguration($mergedConfig['encryption'], $container);
2122
$this->registerMetadataConfiguration($mergedConfig['metadata'], $container);
2223
$this->registerPackagesConfiguration($mergedConfig['packages'], $container);
@@ -29,20 +30,26 @@ protected function loadInternal(array $mergedConfig, ContainerBuilder $container
2930
} else {
3031
$container->setParameter('dirigent.storage.path', $mergedConfig['storage']['path']);
3132
}
32-
33-
$container->setParameter('dirigent.dist_builder.enabled', $mergedConfig['dist_builder']['enabled']);
34-
$container->setParameter('dirigent.dist_builder.dev_packages', $mergedConfig['dist_builder']['dev_packages']);
35-
36-
$container->setParameter('dirigent.dist_mirroring.enabled', $mergedConfig['dist_mirroring']['enabled']);
37-
$container->setParameter('dirigent.dist_mirroring.preferred', $mergedConfig['dist_mirroring']['preferred']);
38-
$container->setParameter('dirigent.dist_mirroring.dev_packages', $mergedConfig['dist_mirroring']['dev_packages']);
3933
}
4034

4135
public function getConfiguration(array $config, ContainerBuilder $container): ConfigurationInterface
4236
{
4337
return new DirigentConfiguration();
4438
}
4539

40+
private function registerDistributionsConfiguration(array $config, ContainerBuilder $container): void
41+
{
42+
$distributionsEnabled = $config['enabled'];
43+
44+
$container->setParameter('dirigent.distributions.enabled', $distributionsEnabled);
45+
$container->setParameter('dirigent.distributions.build', $distributionsEnabled && $config['build']);
46+
$container->setParameter('dirigent.distributions.mirror', $distributionsEnabled && $config['mirror']);
47+
48+
$container->setParameter('dirigent.distributions.async_api_requests', $config['async_api_requests']);
49+
$container->setParameter('dirigent.distributions.dev_versions', $config['dev_versions']);
50+
$container->setParameter('dirigent.distributions.preferred_mirror', $config['preferred_mirror']);
51+
}
52+
4653
/**
4754
* @param array{private_key: ?string, private_key_path: ?string, public_key: ?string, public_key_path: ?string, rotated_keys: array<string>, rotated_key_paths: array<string>} $config
4855
*/
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace CodedMonkey\Dirigent\Message;
4+
5+
use Symfony\Component\Messenger\Attribute\AsMessage;
6+
7+
#[AsMessage]
8+
readonly class ResolveDistribution
9+
{
10+
public function __construct(
11+
public int $versionId,
12+
public string $reference,
13+
public string $type,
14+
) {
15+
}
16+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace CodedMonkey\Dirigent\Message;
4+
5+
use CodedMonkey\Dirigent\Doctrine\Repository\VersionRepository;
6+
use CodedMonkey\Dirigent\Package\PackageDistributionResolver;
7+
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
8+
9+
#[AsMessageHandler]
10+
readonly class ResolveDistributionHandler
11+
{
12+
public function __construct(
13+
private VersionRepository $versionRepository,
14+
private PackageDistributionResolver $distributionResolver,
15+
) {
16+
}
17+
18+
public function __invoke(ResolveDistribution $message): void
19+
{
20+
$version = $this->versionRepository->find($message->versionId);
21+
22+
$this->distributionResolver->resolve($version, $message->reference, $message->type, async: false);
23+
}
24+
}

src/Package/PackageDistributionResolver.php

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use CodedMonkey\Dirigent\Composer\ComposerClient;
66
use CodedMonkey\Dirigent\Composer\ConfigFactory;
77
use CodedMonkey\Dirigent\Doctrine\Entity\Version;
8+
use CodedMonkey\Dirigent\Message\ResolveDistribution;
89
use Composer\IO\NullIO;
910
use Composer\Pcre\Preg;
1011
use Composer\Util\Filesystem as ComposerFilesystem;
@@ -13,18 +14,24 @@
1314
use Composer\Util\Url;
1415
use Symfony\Component\DependencyInjection\Attribute\Autowire;
1516
use Symfony\Component\Filesystem\Filesystem;
17+
use Symfony\Component\Messenger\Envelope;
18+
use Symfony\Component\Messenger\MessageBusInterface;
19+
use Symfony\Component\Messenger\Stamp\TransportNamesStamp;
1620

1721
readonly class PackageDistributionResolver
1822
{
1923
private Filesystem $filesystem;
2024
private string $distributionStoragePath;
2125

2226
public function __construct(
27+
private MessageBusInterface $messenger,
2328
private ComposerClient $composer,
24-
#[Autowire(param: 'dirigent.dist_builder.enabled')]
29+
#[Autowire(param: 'dirigent.distributions.build')]
2530
private bool $buildDistributions,
26-
#[Autowire(param: 'dirigent.dist_builder.dev_packages')]
27-
private bool $buildDevDistributions,
31+
#[Autowire(param: 'dirigent.distributions.mirror')]
32+
private bool $mirrorDistributions,
33+
#[Autowire(param: 'dirigent.distributions.dev_versions')]
34+
private bool $includeDevVersions,
2835
#[Autowire(param: 'dirigent.storage.path')]
2936
string $storagePath,
3037
) {
@@ -42,7 +49,7 @@ public function path(string $packageName, string $versionName, string $reference
4249
return "$this->distributionStoragePath/$packageName/$versionName-$reference.$type";
4350
}
4451

45-
public function resolve(Version $version, string $reference, string $type): bool
52+
public function resolve(Version $version, string $reference, string $type, bool $async): bool
4653
{
4754
$package = $version->getPackage();
4855
$packageName = $package->getName();
@@ -52,17 +59,27 @@ public function resolve(Version $version, string $reference, string $type): bool
5259
return true;
5360
}
5461

55-
if (
56-
null === $version->getDist()
57-
&& $this->buildDistributions
58-
&& (!$version->isDevelopment() || $this->buildDevDistributions)
59-
) {
60-
return $this->build($version, $reference, $type);
61-
} elseif (null !== $version->getDist()) {
62-
return $this->mirror($version, $reference, $type);
62+
if ($version->isDevelopment() && !$this->includeDevVersions) {
63+
return false;
64+
}
65+
66+
if ($async) {
67+
// Resolve the distribution asynchronously so it's available in the future now that we know it was requested
68+
$message = Envelope::wrap(new ResolveDistribution($version->getId(), $reference, $type))
69+
->with(new TransportNamesStamp('async'));
70+
$this->messenger->dispatch($message);
71+
72+
// Still return false so the service resolving the distribution doesn't try to fetch it anyway
73+
return false;
6374
}
6475

65-
return false;
76+
$hasDistribution = null !== $version->getDist();
77+
78+
return match (true) {
79+
$this->buildDistributions && !$hasDistribution => $this->build($version, $reference, $type),
80+
$this->mirrorDistributions && $hasDistribution => $this->mirror($version, $reference, $type),
81+
default => false,
82+
};
6683
}
6784

6885
private function build(Version $version, string $reference, string $type): bool

0 commit comments

Comments
 (0)