From da1f97b29f9ef2f103ac6dc9cc148164beae906f Mon Sep 17 00:00:00 2001 From: Tim Goudriaan Date: Fri, 10 Apr 2026 14:42:21 +0200 Subject: [PATCH 1/4] Add configuration options to retain stale revisions --- docs/configuration-reference.md | 24 +++++++++++++++++++ .../DirigentConfiguration.php | 13 ++++++++++ src/DependencyInjection/DirigentExtension.php | 12 +++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/docs/configuration-reference.md b/docs/configuration-reference.md index 039597c1..391e37bc 100644 --- a/docs/configuration-reference.md +++ b/docs/configuration-reference.md @@ -35,6 +35,10 @@ dirigent: dev_packages: false metadata: mirror_vcs_repositories: false + retain_stale_revisions: + enabled: true + tagged_versions: true + dev_versions: false ``` ## dirigent (root) @@ -131,6 +135,26 @@ Fetch mirrored packages from their VCS repositories by default when possible. Sets the fetch strategy of new mirrored packages to **Fetch from VCS**. +### retain_stale_revisions + +#### enabled + +Type: `boolean` | Default: `true` + +Whether to enable or disable retaining stale revisions of packages. + +#### tagged_versions + +Type: `boolean` | Default: `true` + +Retain stale revisions of tagged package versions. + +#### dev_versions + +Type: `boolean` | Default: `false` + +Retain stale revisions of development package versions. + [iso-8601-durations]: https://en.wikipedia.org/wiki/ISO_8601#Durations [symfony]: https://symfony.com [symfony-docs-config]: https://symfony.com/doc/current/configuration.html diff --git a/src/DependencyInjection/DirigentConfiguration.php b/src/DependencyInjection/DirigentConfiguration.php index af1f62e6..ff760f82 100644 --- a/src/DependencyInjection/DirigentConfiguration.php +++ b/src/DependencyInjection/DirigentConfiguration.php @@ -93,6 +93,19 @@ private function addMetadataSection(ArrayNodeDefinition|NodeDefinition $rootNode ->defaultFalse() ->info('Fetch mirrored packages from their VCS repositories by default when possible.') ->end() + ->arrayNode('retain_stale_revisions') + ->canBeDisabled('Retain stale revisions of package versions.') + ->children() + ->booleanNode('tagged_versions') + ->defaultTrue() + ->info('Retain stale revisions of tagged package versions.') + ->end() + ->booleanNode('dev_versions') + ->defaultFalse() + ->info('Retain stale revisions of development package versions.') + ->end() + ->end() + ->end() ->end() ->end(); } diff --git a/src/DependencyInjection/DirigentExtension.php b/src/DependencyInjection/DirigentExtension.php index 2332e579..4b648b28 100644 --- a/src/DependencyInjection/DirigentExtension.php +++ b/src/DependencyInjection/DirigentExtension.php @@ -56,11 +56,21 @@ private function registerEncryptionConfiguration(array $config, ContainerBuilder } /** - * @param array{mirror_vcs_repositories: bool} $config + * @param array{mirror_vcs_repositories: bool, retain_stale_revisions: array{enabled: bool, tagged_versions: bool, dev_versions: bool}} $config */ private function registerMetadataConfiguration(array $config, ContainerBuilder $container): void { $container->setParameter('dirigent.metadata.mirror_vcs_repositories', $config['mirror_vcs_repositories']); + + $retainStaleRevisions = $config['retain_stale_revisions']['enabled']; + $container->setParameter( + name: 'dirigent.metadata.retain_stale_revisions.tagged_versions', + value: $retainStaleRevisions && $config['retain_stale_revisions']['tagged_versions'], + ); + $container->setParameter( + name: 'dirigent.metadata.retain_stale_revisions.dev_versions', + value: $retainStaleRevisions && $config['retain_stale_revisions']['dev_versions'], + ); } /** From 7a9096b68e60d9b69639c0256710bca98fbfa545 Mon Sep 17 00:00:00 2001 From: Tim Goudriaan Date: Thu, 16 Apr 2026 09:44:12 +0200 Subject: [PATCH 2/4] Implement preliminary pruning of stale metadata revisions --- src/Package/PackageMetadataResolver.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Package/PackageMetadataResolver.php b/src/Package/PackageMetadataResolver.php index a34cf8ae..12888900 100644 --- a/src/Package/PackageMetadataResolver.php +++ b/src/Package/PackageMetadataResolver.php @@ -23,6 +23,7 @@ use Composer\Pcre\Preg; use Composer\Repository\Vcs\VcsDriverInterface; use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Messenger\Stamp\DispatchAfterCurrentBusStamp; use Symfony\Component\Messenger\Stamp\TransportNamesStamp; @@ -36,6 +37,10 @@ public function __construct( private KeywordRepository $keywordRepository, private RegistryRepository $registryRepository, private PackageRepository $packageRepository, + #[Autowire(param: 'dirigent.metadata.retain_stale_revisions.tagged_versions')] + private bool $retainStaleRevisionsTagged, + #[Autowire(param: 'dirigent.metadata.retain_stale_revisions.dev_versions')] + private bool $retainStaleRevisionsDev, ) { } @@ -214,12 +219,18 @@ private function updatePackage(Package $package, array $composerPackages, ?VcsDr private function updateVersion(Version $version, CompletePackageInterface $data, ?VcsDriverInterface $driver = null): void { + $currentMetadata = $version->hasCurrentMetadata() ? $version->getCurrentMetadata() : null; $metadata = $this->createMetadata($version, $data, $driver); - if (!$version->hasCurrentMetadata() || $this->hasMetadataChanged($version->getCurrentMetadata(), $metadata)) { + if (null === $currentMetadata || $this->hasMetadataChanged($currentMetadata, $metadata)) { $version->setCurrentMetadata($metadata); $this->entityManager->persist($metadata); + + $removePreviousMetadata = $version->isDevelopment() ? !$this->retainStaleRevisionsDev : !$this->retainStaleRevisionsTagged; + if (null !== $currentMetadata && $removePreviousMetadata) { + $this->entityManager->remove($currentMetadata); + } } $version->setDefaultBranch($data->isDefaultBranch()); From 8a1280e1d4afdb543e87d38aa350d73169ef0d40 Mon Sep 17 00:00:00 2001 From: Tim Goudriaan Date: Thu, 16 Apr 2026 09:44:57 +0200 Subject: [PATCH 3/4] Add configuration options to retain pruned package versions --- docs/configuration-reference.md | 24 +++++++++++++++++++ .../DirigentConfiguration.php | 13 ++++++++++ src/DependencyInjection/DirigentExtension.php | 12 +++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/docs/configuration-reference.md b/docs/configuration-reference.md index 391e37bc..e7c8118b 100644 --- a/docs/configuration-reference.md +++ b/docs/configuration-reference.md @@ -35,6 +35,10 @@ dirigent: dev_packages: false metadata: mirror_vcs_repositories: false + retain_pruned_versions: + enabled: true + tagged_versions: true + dev_versions: false retain_stale_revisions: enabled: true tagged_versions: true @@ -135,6 +139,26 @@ Fetch mirrored packages from their VCS repositories by default when possible. Sets the fetch strategy of new mirrored packages to **Fetch from VCS**. +### retain_pruned_versions + +#### enabled + +Type: `boolean` | Default: `true` + +Whether to enable or disable retaining pruned versions of packages. + +#### tagged_versions + +Type: `boolean` | Default: `true` + +Retain pruned tagged package versions. + +#### dev_versions + +Type: `boolean` | Default: `false` + +Retain pruned development package versions. + ### retain_stale_revisions #### enabled diff --git a/src/DependencyInjection/DirigentConfiguration.php b/src/DependencyInjection/DirigentConfiguration.php index ff760f82..00b6807f 100644 --- a/src/DependencyInjection/DirigentConfiguration.php +++ b/src/DependencyInjection/DirigentConfiguration.php @@ -93,6 +93,19 @@ private function addMetadataSection(ArrayNodeDefinition|NodeDefinition $rootNode ->defaultFalse() ->info('Fetch mirrored packages from their VCS repositories by default when possible.') ->end() + ->arrayNode('retain_pruned_versions') + ->canBeDisabled('Retain pruned package versions.') + ->children() + ->booleanNode('tagged_versions') + ->defaultTrue() + ->info('Retain pruned tagged package versions.') + ->end() + ->booleanNode('dev_versions') + ->defaultFalse() + ->info('Retain pruned development package versions.') + ->end() + ->end() + ->end() ->arrayNode('retain_stale_revisions') ->canBeDisabled('Retain stale revisions of package versions.') ->children() diff --git a/src/DependencyInjection/DirigentExtension.php b/src/DependencyInjection/DirigentExtension.php index 4b648b28..252a782c 100644 --- a/src/DependencyInjection/DirigentExtension.php +++ b/src/DependencyInjection/DirigentExtension.php @@ -56,12 +56,22 @@ private function registerEncryptionConfiguration(array $config, ContainerBuilder } /** - * @param array{mirror_vcs_repositories: bool, retain_stale_revisions: array{enabled: bool, tagged_versions: bool, dev_versions: bool}} $config + * @param array{mirror_vcs_repositories: bool, retain_stale_revisions: array{enabled: bool, tagged_versions: bool, dev_versions: bool}, retain_pruned_versions: array{enabled: bool, tagged_versions: bool, dev_versions: bool}} $config */ private function registerMetadataConfiguration(array $config, ContainerBuilder $container): void { $container->setParameter('dirigent.metadata.mirror_vcs_repositories', $config['mirror_vcs_repositories']); + $retainPrunedVersions = $config['retain_pruned_versions']['enabled']; + $container->setParameter( + name: 'dirigent.metadata.retain_pruned_versions.tagged_versions', + value: $retainPrunedVersions && $config['retain_pruned_versions']['tagged_versions'], + ); + $container->setParameter( + name: 'dirigent.metadata.retain_pruned_versions.dev_versions', + value: $retainPrunedVersions && $config['retain_pruned_versions']['dev_versions'], + ); + $retainStaleRevisions = $config['retain_stale_revisions']['enabled']; $container->setParameter( name: 'dirigent.metadata.retain_stale_revisions.tagged_versions', From 54659464b150579c18ccd16eea69c6a5316d0bdd Mon Sep 17 00:00:00 2001 From: Tim Goudriaan Date: Thu, 16 Apr 2026 10:23:13 +0200 Subject: [PATCH 4/4] Add pruned property to package version entity --- migrations/Version20260416081737.php | 36 +++++++++++++++++++++++++ src/Doctrine/Entity/Version.php | 13 +++++++++ src/Package/PackageMetadataResolver.php | 14 +++++++++- 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 migrations/Version20260416081737.php diff --git a/migrations/Version20260416081737.php b/migrations/Version20260416081737.php new file mode 100644 index 00000000..4c7dd088 --- /dev/null +++ b/migrations/Version20260416081737.php @@ -0,0 +1,36 @@ +addSql(<<<'SQL' + ALTER TABLE version ADD pruned BOOLEAN DEFAULT NULL + SQL); + $this->addSql(<<<'SQL' + UPDATE version SET pruned = false + SQL); + $this->addSql(<<<'SQL' + ALTER TABLE version ALTER pruned SET NOT NULL + SQL); + } + + public function down(Schema $schema): void + { + $this->addSql(<<<'SQL' + ALTER TABLE version DROP pruned + SQL); + } +} diff --git a/src/Doctrine/Entity/Version.php b/src/Doctrine/Entity/Version.php index 85546f54..bb5ec140 100644 --- a/src/Doctrine/Entity/Version.php +++ b/src/Doctrine/Entity/Version.php @@ -23,6 +23,9 @@ class Version extends TrackedEntity implements \Stringable #[ORM\Column] private bool $development; + #[ORM\Column] + private bool $pruned = false; + #[ORM\Column] private bool $defaultBranch = false; @@ -91,6 +94,16 @@ public function setDevelopment(bool $development): void $this->development = $development; } + public function isPruned(): bool + { + return $this->pruned; + } + + public function setPruned(bool $pruned): void + { + $this->pruned = $pruned; + } + public function isDefaultBranch(): bool { return $this->defaultBranch; diff --git a/src/Package/PackageMetadataResolver.php b/src/Package/PackageMetadataResolver.php index 12888900..74870fe4 100644 --- a/src/Package/PackageMetadataResolver.php +++ b/src/Package/PackageMetadataResolver.php @@ -41,6 +41,10 @@ public function __construct( private bool $retainStaleRevisionsTagged, #[Autowire(param: 'dirigent.metadata.retain_stale_revisions.dev_versions')] private bool $retainStaleRevisionsDev, + #[Autowire(param: 'dirigent.metadata.retain_pruned_versions.tagged_versions')] + private bool $retainPrunedVersionsTagged, + #[Autowire(param: 'dirigent.metadata.retain_pruned_versions.dev_versions')] + private bool $retainPrunedVersionsDev, ) { } @@ -209,7 +213,15 @@ private function updatePackage(Package $package, array $composerPackages, ?VcsDr // Remove outdated versions foreach ($existingVersionMetadata as $version) { - $this->entityManager->remove($version); + $removeVersion = $version->isDevelopment() ? !$this->retainPrunedVersionsDev : !$this->retainPrunedVersionsTagged; + if ($removeVersion) { + $this->entityManager->remove($version); + } else { + $version->setPruned(true); + $version->setUpdatedAt(new \DateTimeImmutable()); + + $this->entityManager->persist($version); + } } $package->setUpdatedAt(new \DateTimeImmutable());