Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

!!! TASK: Use generator to yield information instead of stateful `onP… #3397

Open
wants to merge 1 commit into
base: 9.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions Neos.Flow/Classes/Command/ResourceCommandController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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.');
Expand Down
5 changes: 4 additions & 1 deletion Neos.Flow/Classes/ResourceManagement/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<ResourcePublishResult>
*/
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);
}
}

Expand Down
29 changes: 5 additions & 24 deletions Neos.Flow/Classes/ResourceManagement/Target/FileSystemTarget.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down Expand Up @@ -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.
Expand All @@ -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<ResourcePublishResult>
*/
public function publishCollection(CollectionInterface $collection)
public function publishCollection(CollectionInterface $collection): \Generator
{
$storage = $collection->getStorage();
$this->checkAndRemovePackageSymlinks($storage);
Expand All @@ -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++;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Neos\Flow\ResourceManagement\Target;

/**
* Yielded by the implementation of an {@see TargetInterface} after each resource publishing
*/
final readonly class ResourcePublishResult
{
public function __construct(
public int $iteration,
public string $message,
public mixed $metaData = null
) {
}
}
11 changes: 2 additions & 9 deletions Neos.Flow/Classes/ResourceManagement/Target/TargetInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ public function getName();
* Publishes the whole collection to this target
*
* @param CollectionInterface $collection The collection to publish
* @return void
* @return \Generator<ResourcePublishResult> 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
Expand Down Expand Up @@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}
}
Loading