|
14 | 14 | use CodedMonkey\Dirigent\Package\PackageDistributionResolver; |
15 | 15 | use CodedMonkey\Dirigent\Package\PackageMetadataResolver; |
16 | 16 | use CodedMonkey\Dirigent\Package\PackageProviderManager; |
| 17 | +use Doctrine\ORM\EntityManagerInterface; |
17 | 18 | use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; |
18 | 19 | use Symfony\Component\DependencyInjection\Attribute\Autowire; |
19 | 20 | use Symfony\Component\HttpFoundation\BinaryFileResponse; |
|
31 | 32 | class ApiController extends AbstractController |
32 | 33 | { |
33 | 34 | public function __construct( |
| 35 | + private readonly EntityManagerInterface $entityManager, |
34 | 36 | private readonly PackageRepository $packageRepository, |
35 | 37 | private readonly VersionRepository $versionRepository, |
36 | 38 | private readonly PackageMetadataResolver $metadataResolver, |
37 | 39 | private readonly PackageDistributionResolver $distributionResolver, |
38 | 40 | private readonly PackageProviderManager $providerManager, |
39 | 41 | private readonly MessageBusInterface $messenger, |
| 42 | + #[Autowire(param: 'dirigent.packages.dynamic_updates')] |
| 43 | + private readonly bool $dynamicUpdatesEnabled, |
40 | 44 | #[Autowire(param: 'dirigent.metadata.mirror_vcs_repositories')] |
41 | 45 | private readonly bool $mirrorVcsRepositories = false, |
42 | 46 | ) { |
@@ -81,15 +85,13 @@ public function root(RouterInterface $router): JsonResponse |
81 | 85 | #[IsGrantedAccess] |
82 | 86 | public function packageMetadata(Request $request): Response |
83 | 87 | { |
84 | | - $packageName = $request->attributes->get('package'); |
| 88 | + $packageName = $request->attributes->getString('package'); |
85 | 89 | $basePackageName = u($packageName)->trimSuffix('~dev')->toString(); |
86 | 90 |
|
87 | | - if (null === $package = $this->findPackage($basePackageName)) { |
| 91 | + if (null === $this->findPackage($basePackageName)) { |
88 | 92 | throw $this->createNotFoundException(); |
89 | 93 | } |
90 | 94 |
|
91 | | - $this->messenger->dispatch(new UpdatePackage($package->getId(), PackageUpdateSource::Dynamic)); |
92 | | - |
93 | 95 | if (!$this->providerManager->exists($packageName)) { |
94 | 96 | throw $this->createNotFoundException(); |
95 | 97 | } |
@@ -126,8 +128,6 @@ public function packageDistribution(Request $request, string $reference, string |
126 | 128 | throw $this->createNotFoundException(); |
127 | 129 | } |
128 | 130 |
|
129 | | - $this->messenger->dispatch(new UpdatePackage($package->getId(), PackageUpdateSource::Dynamic)); |
130 | | - |
131 | 131 | if (null === $version = $this->versionRepository->findOneByNormalizedVersion($package, $versionName)) { |
132 | 132 | throw $this->createNotFoundException(); |
133 | 133 | } |
@@ -167,24 +167,41 @@ public function trackInstallations(Request $request): Response |
167 | 167 | return new JsonResponse(['status' => 'success'], Response::HTTP_CREATED); |
168 | 168 | } |
169 | 169 |
|
170 | | - private function findPackage(string $packageName): ?Package |
| 170 | + private function findPackage(string $packageName, ?bool $create = false): ?Package |
171 | 171 | { |
172 | | - // Search for the package in the database |
173 | | - if (null !== $package = $this->packageRepository->findOneByName($packageName)) { |
174 | | - return $package; |
175 | | - } |
| 172 | + $this->entityManager->beginTransaction(); |
| 173 | + |
| 174 | + try { |
| 175 | + // Search for the package in the database |
| 176 | + if (null === $package = $this->packageRepository->findOneByName($packageName)) { |
| 177 | + if (!$create || !$this->dynamicUpdatesEnabled) { |
| 178 | + // It doesn't exist in the database and we can't create it dynamically |
| 179 | + return null; |
| 180 | + } |
| 181 | + |
| 182 | + // Search for the package in external registries |
| 183 | + if (null === $registry = $this->metadataResolver->findPackageProvider($packageName)) { |
| 184 | + return null; |
| 185 | + } |
| 186 | + |
| 187 | + $package = new Package(); |
| 188 | + $package->setName($packageName); |
| 189 | + $package->setMirrorRegistry($registry); |
| 190 | + $package->setFetchStrategy($this->mirrorVcsRepositories ? PackageFetchStrategy::Vcs : PackageFetchStrategy::Mirror); |
| 191 | + |
| 192 | + $this->packageRepository->save($package, true); |
| 193 | + } |
176 | 194 |
|
177 | | - // Attempt to find a package from external registries |
178 | | - if (null === $registry = $this->metadataResolver->findPackageProvider($packageName)) { |
179 | | - return null; |
180 | | - } |
| 195 | + if ($this->dynamicUpdatesEnabled) { |
| 196 | + $this->messenger->dispatch(new UpdatePackage($package->getId(), PackageUpdateSource::Dynamic)); |
| 197 | + } |
| 198 | + } catch (\Throwable $exception) { |
| 199 | + $this->entityManager->rollback(); |
181 | 200 |
|
182 | | - $package = new Package(); |
183 | | - $package->setName($packageName); |
184 | | - $package->setMirrorRegistry($registry); |
185 | | - $package->setFetchStrategy($this->mirrorVcsRepositories ? PackageFetchStrategy::Vcs : PackageFetchStrategy::Mirror); |
| 201 | + throw $exception; |
| 202 | + } |
186 | 203 |
|
187 | | - $this->packageRepository->save($package, true); |
| 204 | + $this->entityManager->commit(); |
188 | 205 |
|
189 | 206 | return $package; |
190 | 207 | } |
|
0 commit comments