From abde32b3bc63e42de4f0435de465aee1d453dc9f Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Thu, 26 Sep 2024 17:14:54 +0200 Subject: [PATCH] !!! TASK: Use generator to yield information instead of stateful `onPublish` callback registration Followup to https://github.com/neos/flow-development-collection/pull/3229 --- .../Command/ResourceCommandController.php | 16 +++++----- .../Classes/ResourceManagement/Collection.php | 5 +++- .../Target/FileSystemSymlinkTarget.php | 9 +++--- .../Target/FileSystemTarget.php | 29 ++++--------------- .../Target/ResourcePublishResult.php | 18 ++++++++++++ .../Target/TargetInterface.php | 11 ++----- .../Target/FileSystemTargetTest.php | 18 ++++++------ 7 files changed, 50 insertions(+), 56 deletions(-) create mode 100644 Neos.Flow/Classes/ResourceManagement/Target/ResourcePublishResult.php diff --git a/Neos.Flow/Classes/Command/ResourceCommandController.php b/Neos.Flow/Classes/Command/ResourceCommandController.php index 6bb37ce5d0..486467ddfe 100644 --- a/Neos.Flow/Classes/Command/ResourceCommandController.php +++ b/Neos.Flow/Classes/Command/ResourceCommandController.php @@ -104,14 +104,11 @@ public function publishCommand(string $collection = null, bool $quiet = false) $progressIndicator?->start('Published 0'); $target = $collection->getTarget(); $lastIteration = 0; - $target->onPublish(function ($iteration) use ($progressIndicator, &$lastIteration) { - $iteration += 1; + foreach ($target->publishCollection($collection) as $publishResult) { $progressIndicator?->advance(); - $progressIndicator?->setMessage(sprintf('Published %s', $iteration)); - $this->clearState($iteration); - $lastIteration = $iteration; - }); - $target->publishCollection($collection); + $progressIndicator?->setMessage(sprintf('Published %s', $lastIteration = $publishResult->iteration + 1)); + $this->clearState($publishResult->iteration); + } $progressIndicator?->finish(sprintf('Published %s', $lastIteration)); } catch (Exception $exception) { $message = sprintf( @@ -192,7 +189,10 @@ public function copyCommand(string $sourceCollection, string $targetCollection, if ($publish) { $this->outputLine('Publishing copied resources to the target "%s" ...', [$targetCollection->getTarget()->getName()]); - $targetCollection->getTarget()->publishCollection($sourceCollection); + $publisher = $targetCollection->getTarget()->publishCollection($sourceCollection); + while ($publisher->valid()) { + $publisher->next(); + } } $this->outputLine('Done.'); diff --git a/Neos.Flow/Classes/ResourceManagement/Collection.php b/Neos.Flow/Classes/ResourceManagement/Collection.php index 6b07307bb0..73d95dde7e 100644 --- a/Neos.Flow/Classes/ResourceManagement/Collection.php +++ b/Neos.Flow/Classes/ResourceManagement/Collection.php @@ -146,7 +146,10 @@ public function importResourceFromContent($content) */ public function publish() { - $this->target->publishCollection($this); + $publisher = $this->target->publishCollection($this); + while ($publisher->valid()) { + $publisher->next(); + } } /** diff --git a/Neos.Flow/Classes/ResourceManagement/Target/FileSystemSymlinkTarget.php b/Neos.Flow/Classes/ResourceManagement/Target/FileSystemSymlinkTarget.php index f6e808cdbe..db31b41352 100644 --- a/Neos.Flow/Classes/ResourceManagement/Target/FileSystemSymlinkTarget.php +++ b/Neos.Flow/Classes/ResourceManagement/Target/FileSystemSymlinkTarget.php @@ -32,21 +32,20 @@ class FileSystemSymlinkTarget extends FileSystemTarget * Publishes the whole collection to this target * * @param CollectionInterface $collection The collection to publish - * @return void + * @return \Generator */ - public function publishCollection(CollectionInterface $collection) + public function publishCollection(CollectionInterface $collection): \Generator { $storage = $collection->getStorage(); if ($storage instanceof PackageStorage) { $iteration = 0; foreach ($storage->getPublicResourcePaths() as $packageKey => $path) { $this->publishDirectory($path, $packageKey); - // Note that the callback is only invoked once per resource public directory of each package. Instead of for each storage object. - $this->invokeOnPublishCallbacks($iteration); + yield new ResourcePublishResult($iteration, sprintf('Package %s was published to %s', $packageKey, $path), compact('packageKey', 'path')); $iteration++; } } else { - parent::publishCollection($collection); + yield from parent::publishCollection($collection); } } diff --git a/Neos.Flow/Classes/ResourceManagement/Target/FileSystemTarget.php b/Neos.Flow/Classes/ResourceManagement/Target/FileSystemTarget.php index c2d2b9a086..a699879239 100644 --- a/Neos.Flow/Classes/ResourceManagement/Target/FileSystemTarget.php +++ b/Neos.Flow/Classes/ResourceManagement/Target/FileSystemTarget.php @@ -44,11 +44,6 @@ class FileSystemTarget implements TargetInterface */ protected $name; - /** - * @var list<\Closure(int $iteration): void> - */ - protected $callbacks = []; - /** * The path (in a filesystem) where resources are published to * @@ -170,21 +165,6 @@ public function getName() return $this->name; } - /** - * @param \Closure(int $iteration): void $callback Function called after each resource publishing - */ - public function onPublish(\Closure $callback): void - { - $this->callbacks[] = $callback; - } - - protected function invokeOnPublishCallbacks(int $iteration): void - { - foreach ($this->callbacks as $callback) { - $callback($iteration); - } - } - /** * Checks if the PackageStorage has been previously initialized with symlinks * and clears them. Otherwise the original sources would be overwritten. @@ -209,9 +189,9 @@ protected function checkAndRemovePackageSymlinks(StorageInterface $storage) * Publishes the whole collection to this target * * @param CollectionInterface $collection The collection to publish - * @return void + * @return \Generator */ - public function publishCollection(CollectionInterface $collection) + public function publishCollection(CollectionInterface $collection): \Generator { $storage = $collection->getStorage(); $this->checkAndRemovePackageSymlinks($storage); @@ -223,10 +203,11 @@ public function publishCollection(CollectionInterface $collection) continue; } - $this->publishFile($sourceStream, $this->getRelativePublicationPathAndFilename($object)); + $filePath = $this->getRelativePublicationPathAndFilename($object); + $this->publishFile($sourceStream, $filePath); fclose($sourceStream); - $this->invokeOnPublishCallbacks($iteration); + yield new ResourcePublishResult($iteration, sprintf('File %s was published', $filePath), $object); $iteration++; } } diff --git a/Neos.Flow/Classes/ResourceManagement/Target/ResourcePublishResult.php b/Neos.Flow/Classes/ResourceManagement/Target/ResourcePublishResult.php new file mode 100644 index 0000000000..9460bd8ba5 --- /dev/null +++ b/Neos.Flow/Classes/ResourceManagement/Target/ResourcePublishResult.php @@ -0,0 +1,18 @@ + The publisher generator with the current publish result as value containing iteration information and metadata. */ - public function publishCollection(CollectionInterface $collection); + public function publishCollection(CollectionInterface $collection): \Generator; /** * Publishes the given persistent resource from the given storage @@ -68,11 +68,4 @@ public function getPublicStaticResourceUri($relativePathAndFilename); * @throws Exception */ public function getPublicPersistentResourceUri(PersistentResource $resource); - - /** - * Registers a callback, which must be invoked by the implementation after each resource publishing - * - * @param \Closure(int $iteration): void $callback - */ - public function onPublish(\Closure $callback): void; } diff --git a/Neos.Flow/Tests/Unit/ResourceManagement/Target/FileSystemTargetTest.php b/Neos.Flow/Tests/Unit/ResourceManagement/Target/FileSystemTargetTest.php index 98556d63d7..d6dd83e3e3 100644 --- a/Neos.Flow/Tests/Unit/ResourceManagement/Target/FileSystemTargetTest.php +++ b/Neos.Flow/Tests/Unit/ResourceManagement/Target/FileSystemTargetTest.php @@ -18,6 +18,7 @@ use Neos\Flow\ResourceManagement\Collection; use Neos\Flow\ResourceManagement\PersistentResource; use Neos\Flow\ResourceManagement\Storage\PackageStorage; +use Neos\Flow\ResourceManagement\Storage\StorageObject; use Neos\Flow\ResourceManagement\Target\FileSystemTarget; use Neos\Flow\Tests\UnitTestCase; use org\bovigo\vfs\vfsStream; @@ -192,20 +193,19 @@ public function getWorksWithPackageStorage() $this->inject($packageStorage, 'packageManager', $packageManager); - $oneResourcePublished = false; - - $_publicationCallback = function ($i) use (&$oneResourcePublished) { - $oneResourcePublished = true; - }; - $staticCollection = new Collection('testStaticCollection', $packageStorage, $this->fileSystemTarget, ['*']); $fileSystemTarget = new FileSystemTarget('test', ['path' => 'vfs://Test/Publish']); $fileSystemTarget->initializeObject(ObjectManagerInterface::INITIALIZATIONCAUSE_CREATED); $fileSystemTarget->injectLogger($mockSystemLogger); - $fileSystemTarget->onPublish($_publicationCallback); - $fileSystemTarget->publishCollection($staticCollection); - self::assertTrue($oneResourcePublished); + $publishResults = iterator_to_array($fileSystemTarget->publishCollection($staticCollection)); + self::assertCount(1, $publishResults); + + foreach ($publishResults as $publishResult) { + self::assertSame('File Some.Testing.Package/Test/Packages/Application/Some.Testing.Package/composer.json was published', $publishResult->message); + self::assertSame(0, $publishResult->iteration); + self::assertInstanceOf(StorageObject::class, $publishResult->metaData); + } } }