diff --git a/Neos.ContentRepository.NodeMigration/src/Command/ExecuteMigration.php b/Neos.ContentRepository.NodeMigration/src/Command/ExecuteMigration.php index ed34f8d0a43..65f5fab56e6 100644 --- a/Neos.ContentRepository.NodeMigration/src/Command/ExecuteMigration.php +++ b/Neos.ContentRepository.NodeMigration/src/Command/ExecuteMigration.php @@ -22,16 +22,6 @@ */ final class ExecuteMigration { - /** - * @var MigrationConfiguration - */ - private $migrationConfiguration; - - /** - * @var WorkspaceName - */ - private $workspaceName; - /** * This property exists mostly for testing, to make the command handler fully deterministic. * @@ -55,42 +45,29 @@ final class ExecuteMigration /** * ExecuteMigration constructor. - * @param MigrationConfiguration $migrationConfiguration - * @param WorkspaceName $workspaceName * @param ContentStreamId[] $contentStreamIdsForWriting */ public function __construct( - MigrationConfiguration $migrationConfiguration, - WorkspaceName $workspaceName, + private readonly MigrationConfiguration $migrationConfiguration, + private readonly WorkspaceName $workspaceName, + private readonly ?WorkspaceName $targetWorkspaceName, array $contentStreamIdsForWriting = [] ) { - $this->migrationConfiguration = $migrationConfiguration; - $this->workspaceName = $workspaceName; $this->contentStreamIdsForWriting = array_values($contentStreamIdsForWriting); } - /** - * @return MigrationConfiguration - */ public function getMigrationConfiguration(): MigrationConfiguration { return $this->migrationConfiguration; } - /** - * @return WorkspaceName - */ public function getWorkspaceName(): WorkspaceName { return $this->workspaceName; } - public function getOrCreateContentStreamIdForWriting(int $index): ContentStreamId + public function getTargetWorkspaceName(): ?WorkspaceName { - if (isset($this->contentStreamIdsForWriting[$index])) { - return $this->contentStreamIdsForWriting[$index]; - } - - return ContentStreamId::create(); + return $this->targetWorkspaceName; } } diff --git a/Neos.ContentRepository.NodeMigration/src/NodeMigrationService.php b/Neos.ContentRepository.NodeMigration/src/NodeMigrationService.php index ccf503359f6..5cde0a8d8a7 100644 --- a/Neos.ContentRepository.NodeMigration/src/NodeMigrationService.php +++ b/Neos.ContentRepository.NodeMigration/src/NodeMigrationService.php @@ -66,22 +66,30 @@ public function executeMigration(ExecuteMigration $command): void ), 1611688225); } - foreach ($command->getMigrationConfiguration()->getMigration() as $step => $migrationDescription) { - $contentStreamForWriting = $command->getOrCreateContentStreamIdForWriting($step); + if ($command->getTargetWorkspaceName() !== null) { + $targetWorkspace = $this->contentRepository->getWorkspaceFinder()->findOneByName($command->getTargetWorkspaceName()); + } + + if ($targetWorkspace) { + $targetContentStreamId = $targetWorkspace->currentContentStreamId; + } else { + $targetContentStreamId = ContentStreamId::create(); $this->contentRepository->handle( CreateWorkspace::create( - WorkspaceName::fromString($contentStreamForWriting->value), + $command->getTargetWorkspaceName() ?? WorkspaceName::fromString($targetContentStreamId->value), $workspace->workspaceName, - WorkspaceTitle::fromString($contentStreamForWriting->value), + WorkspaceTitle::fromString($command->getTargetWorkspaceName()?->value ?? $targetContentStreamId->value), WorkspaceDescription::fromString(''), - $contentStreamForWriting, + $targetContentStreamId, ) )->block(); + } + foreach ($command->getMigrationConfiguration()->getMigration() as $migrationDescription) { /** array $migrationDescription */ $this->executeSubMigrationAndBlock( $migrationDescription, $workspace->currentContentStreamId, - $contentStreamForWriting + $targetContentStreamId ); } } diff --git a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/MigrationsTrait.php b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/MigrationsTrait.php index 154a8337ea7..69d9624dd44 100644 --- a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/MigrationsTrait.php +++ b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/MigrationsTrait.php @@ -35,12 +35,9 @@ trait MigrationsTrait */ public function iRunTheFollowingNodeMigration(string $workspaceName, string $contentStreams, PyStringNode $string): void { + // TODO: Replace ContentStream with Workspace $migrationConfiguration = new MigrationConfiguration(Yaml::parse($string->getRaw())); - $contentStreamIds = array_map( - fn (string $cs) => ContentStreamId::fromString($cs), - explode(',', $contentStreams) - ); - $command = new ExecuteMigration($migrationConfiguration, WorkspaceName::fromString($workspaceName), $contentStreamIds); + $command = new ExecuteMigration($migrationConfiguration, WorkspaceName::fromString($workspaceName), null); /** @var NodeMigrationService $nodeMigrationService */ $nodeMigrationService = $this->getContentRepositoryService(new NodeMigrationServiceFactory()); diff --git a/Neos.ContentRepositoryRegistry/Classes/Command/NodeMigrationCommandController.php b/Neos.ContentRepositoryRegistry/Classes/Command/NodeMigrationCommandController.php index d600334d299..e6fa84bc972 100644 --- a/Neos.ContentRepositoryRegistry/Classes/Command/NodeMigrationCommandController.php +++ b/Neos.ContentRepositoryRegistry/Classes/Command/NodeMigrationCommandController.php @@ -34,7 +34,6 @@ #[Flow\Scope('singleton')] class NodeMigrationCommandController extends CommandController { - public function __construct( private readonly MigrationFactory $migrationFactory, private readonly ContentRepositoryRegistry $contentRepositoryRegistry, @@ -49,13 +48,16 @@ public function __construct( * * @param string $version The version of the migration configuration you want to use. * @param string $workspace The workspace where the migration should be applied; by default "live" + * @param ?string $targetWorkspace The workspace where the migration result should end; by default "live". If set to null, each migration creates a new workspace for selectiv publishing. * @param boolean $force Confirm application of this migration, only needed if the given migration contains any warnings. * @return void * @throws StopCommandException * @see neos.contentrepositoryregistry:nodemigration:execute */ - public function executeCommand(string $version, string $workspace = 'live', bool $force = false, string $contentRepositoryIdentifier = 'default'): void + public function executeCommand(string $version, string $workspace = 'live', ?string $targetWorkspace = 'live', bool $force = false, string $contentRepositoryIdentifier = 'default'): void { + $workspace = WorkspaceName::fromString($workspace); + $targetWorkspace = $targetWorkspace === null ?: WorkspaceName::fromString($targetWorkspace); $contentRepositoryId = ContentRepositoryId::fromString($contentRepositoryIdentifier); try { @@ -73,9 +75,13 @@ public function executeCommand(string $version, string $workspace = 'live', bool $nodeMigrationService->executeMigration( new ExecuteMigration( $migrationConfiguration, - WorkspaceName::fromString($workspace) + $workspace, + $targetWorkspace, ) ); + + // Rebase depending workspaces? + $this->outputLine(); $this->outputLine('Successfully applied migration.'); } catch (MigrationException $e) {