has(ExtensionRegistry::class) === false) { return; } $registry = $container->findDefinition(ExtensionRegistry::class); $packages = array_keys($container->findTaggedServiceIds(ExtensionInterface::CONTAINER_TAG)); $this->projectDir = $container->getParameter('kernel.project_dir'); /* @see ExtensionRegistry::addCompilerPass() */ $registry->addMethodCall('addCompilerPass', [$packages]); // Rebuild our own `packages/bolt.yaml` file. $this->buildServices($packages); } public function buildServices(array $packages): void { $services = [ 'services' => [ '_defaults' => [ 'autowire' => true, 'autoconfigure' => true, ], ], ]; $packages = $this->addComposerPackages($packages); foreach ($packages as $package) { [$name, $service] = $this->createService($package); if ($name) { $services['services'][$name] = $service; } } $yaml = "# This file is auto-generated by Bolt. Do not modify.\n\n"; $yaml .= Yaml::dump($services, 3); $filename = $this->projectDir . '/config/services_bolt.yaml'; file_put_contents($filename, $yaml); } private function createService(string $package): array { if (! class_exists($package)) { return [null, null]; } $reflection = new \ReflectionClass($package); $namespace = Str::removeLast($reflection->getName(), Str::splitLast($reflection->getName(), '\\')); $path = $this->getRelativePath($package); return [ $namespace, [ 'resource' => $path . '/*', 'exclude' => $path . '/{Entity,Exception}', ], ]; } private function addComposerPackages(array $packages): array { $composerPackages = Types::get('bolt-extension'); /** @var PackageInterface $package */ foreach ($composerPackages as $package) { $extra = $package->getExtra(); if (array_key_exists('entrypoint', $extra)) { $packages[] = $extra['entrypoint']; } } sort($packages); return array_unique($packages); } private function getRelativePath(string $package): string { $reflection = new \ReflectionClass($package); // We add the `/foo` to make the path start with `../` return Path::makeRelative(dirname($reflection->getFileName()), $this->projectDir . '/foo'); } }