diff --git a/Neos.ContentRepositoryRegistry/Classes/Command/WorkspaceCommandController.php b/Neos.ContentRepositoryRegistry/Classes/Command/WorkspaceCommandController.php deleted file mode 100644 index a71011fd7a4..00000000000 --- a/Neos.ContentRepositoryRegistry/Classes/Command/WorkspaceCommandController.php +++ /dev/null @@ -1,38 +0,0 @@ -contentRepositoryRegistry->buildService( - $contentRepositoryId, - new WorkspaceMaintenanceServiceFactory() - ); - $outdatedWorkspaces = $workspaceMaintenanceService->rebaseOutdatedWorkspaces(); - - if (!count($outdatedWorkspaces)) { - $this->outputLine('There are no outdated workspaces.'); - } else { - foreach ($outdatedWorkspaces as $outdatedWorkspace) { - $this->outputFormatted('Rebased workspace %s', [$outdatedWorkspace]); - } - } - } -} diff --git a/Neos.Neos/Classes/Command/WorkspaceCommandController.php b/Neos.Neos/Classes/Command/WorkspaceCommandController.php index 4aae325910f..f9d433a6882 100644 --- a/Neos.Neos/Classes/Command/WorkspaceCommandController.php +++ b/Neos.Neos/Classes/Command/WorkspaceCommandController.php @@ -22,6 +22,7 @@ use Neos\ContentRepository\Core\Feature\WorkspacePublication\Command\DiscardWorkspace; use Neos\ContentRepository\Core\Feature\WorkspacePublication\Command\PublishWorkspace; use Neos\ContentRepository\Core\Projection\Workspace\Workspace; +use Neos\ContentRepository\Core\Service\WorkspaceMaintenanceServiceFactory; use Neos\ContentRepository\Core\SharedModel\Exception\WorkspaceDoesNotExist; use Neos\ContentRepository\Core\SharedModel\User\UserId; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; @@ -31,22 +32,18 @@ use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Flow\Annotations as Flow; use Neos\Flow\Cli\CommandController; +use Neos\Flow\Cli\Exception\StopCommandException; use Neos\Flow\Persistence\PersistenceManagerInterface; use Neos\Neos\Domain\Service\UserService; -use Symfony\Component\Serializer\Exception\ExceptionInterface; /** * The Workspace Command Controller - * - * @Flow\Scope("singleton") */ +#[Flow\Scope('singleton')] class WorkspaceCommandController extends CommandController { - /** - * @Flow\Inject - * @var UserService - */ - protected $userService; + #[Flow\Inject] + protected UserService $userService; #[Flow\Inject] protected PersistenceManagerInterface $persistenceManager; @@ -58,34 +55,23 @@ class WorkspaceCommandController extends CommandController * Publish changes of a workspace * * This command publishes all modified, created or deleted nodes in the specified workspace to its base workspace. - * If a target workspace is specified, the content is published to that workspace instead. * * @param string $workspace Name of the workspace containing the changes to publish, for example "user-john" * @param string $contentRepositoryIdentifier - * @param boolean $verbose If enabled, some information about individual nodes will be displayed - * @param boolean $dryRun If set, only displays which nodes would be published, no real changes are committed - * @return void - * @throws ExceptionInterface */ - public function publishCommand( - $workspace, - string $contentRepositoryIdentifier = 'default', - $verbose = false, - $dryRun = false - ) { + public function publishCommand(string $workspace, string $contentRepositoryIdentifier = 'default'): void + { $contentRepositoryId = ContentRepositoryId::fromString($contentRepositoryIdentifier); $contentRepository = $this->contentRepositoryRegistry->get($contentRepositoryId); - if (!$dryRun) { - $contentRepository->handle(new PublishWorkspace( - WorkspaceName::fromString($workspace), - ))->block(); + $contentRepository->handle(new PublishWorkspace( + WorkspaceName::fromString($workspace), + ))->block(); - $this->outputLine( - 'Published all nodes in workspace %s to its base workspace', - [$workspace] - ); - } + $this->outputLine( + 'Published all nodes in workspace %s to its base workspace', + [$workspace] + ); } /** @@ -94,34 +80,33 @@ public function publishCommand( * This command discards all modified, created or deleted nodes in the specified workspace. * * @param string $workspace Name of the workspace, for example "user-john" - * @param boolean $verbose If enabled, information about individual nodes will be displayed - * @param boolean $dryRun If set, only displays which nodes would be discarded, no real changes are committed - * @return void + * @param string $contentRepositoryIdentifier + * @throws StopCommandException */ - public function discardCommand( - $workspace, - string $contentRepositoryIdentifier = 'default', - $verbose = false, - $dryRun = false - ) { + public function discardCommand(string $workspace, string $contentRepositoryIdentifier = 'default'): void + { $contentRepositoryId = ContentRepositoryId::fromString($contentRepositoryIdentifier); $contentRepository = $this->contentRepositoryRegistry->get($contentRepositoryId); - if (!$dryRun) { - try { - $contentRepository->handle( - DiscardWorkspace::create( - WorkspaceName::fromString($workspace), - ) - )->block(); - } catch (WorkspaceDoesNotExist $exception) { - $this->outputLine('Workspace "%s" does not exist', [$workspace]); - $this->quit(1); - } - $this->outputLine('Discarded all nodes in workspace %s', [$workspace]); + try { + $contentRepository->handle( + DiscardWorkspace::create( + WorkspaceName::fromString($workspace), + ) + )->block(); + } catch (WorkspaceDoesNotExist $exception) { + $this->outputLine('Workspace "%s" does not exist', [$workspace]); + $this->quit(1); } + $this->outputLine('Discarded all nodes in workspace %s', [$workspace]); } + /** + * Create a new root workspace for a content repository. + * + * @param string $name + * @param string $contentRepositoryIdentifier + */ public function createRootCommand(string $name, string $contentRepositoryIdentifier = 'default'): void { $contentRepositoryId = ContentRepositoryId::fromString($contentRepositoryIdentifier); @@ -142,26 +127,28 @@ public function createRootCommand(string $name, string $contentRepositoryIdentif * * @param string $workspace Name of the workspace, for example "christmas-campaign" * @param string $baseWorkspace Name of the base workspace. If none is specified, "live" is assumed. - * @param string $title Human friendly title of the workspace, for example "Christmas Campaign" - * @param string $description A description explaining the purpose of the new workspace + * @param string|null $title Human friendly title of the workspace, for example "Christmas Campaign" + * @param string|null $description A description explaining the purpose of the new workspace * @param string $owner The identifier of a User to own the workspace - * @return void + * @param string $contentRepositoryIdentifier + * @throws StopCommandException */ public function createCommand( - $workspace, - $baseWorkspace = 'live', - $title = null, - $description = null, - $owner = '', + string $workspace, + string $baseWorkspace = 'live', + string $title = null, + string $description = null, + string $owner = '', string $contentRepositoryIdentifier = 'default' - ) { + ): void { $contentRepositoryId = ContentRepositoryId::fromString($contentRepositoryIdentifier); $contentRepository = $this->contentRepositoryRegistry->get($contentRepositoryId); if ($owner === '') { - $workspaceOwner = null; + $workspaceOwnerUserId = null; } else { - $workspaceOwner = $this->userService->getCurrentUserIdentifier(); + $workspaceOwnerUserId = UserId::fromString($owner); + $workspaceOwner = $this->userService->findByUserIdentifier($workspaceOwnerUserId); if ($workspaceOwner === null) { $this->outputLine('The user "%s" specified as owner does not exist', [$owner]); $this->quit(3); @@ -175,7 +162,7 @@ public function createCommand( WorkspaceTitle::fromString($title ?: $workspace), WorkspaceDescription::fromString($description ?: $workspace), ContentStreamId::create(), - $workspaceOwner + $workspaceOwnerUserId ))->block(); } catch (WorkspaceAlreadyExists $workspaceAlreadyExists) { $this->outputLine('Workspace "%s" already exists', [$workspace]); @@ -185,7 +172,7 @@ public function createCommand( $this->quit(2); } - if ($workspaceOwner instanceof UserId) { + if ($workspaceOwnerUserId instanceof UserId) { $this->outputLine( 'Created a new workspace "%s", based on workspace "%s", owned by "%s".', [$workspace, $baseWorkspace, $owner] @@ -206,10 +193,9 @@ public function createCommand( * * @param string $workspace Name of the workspace, for example "christmas-campaign" * @param boolean $force Delete the workspace and all of its contents - * @return void * @see neos.neos:workspace:discard */ - public function deleteCommand($workspace, $force = false, string $contentRepositoryIdentifier = 'default') + public function deleteCommand(string $workspace, bool $force = false, string $contentRepositoryIdentifier = 'default'): void { throw new \BadMethodCallException( 'Workspace removal is not supported yet', @@ -290,56 +276,32 @@ public function deleteCommand($workspace, $force = false, string $contentReposit } /** - * Rebase a workspace - * - * This command sets a new base workspace for the specified workspace. Note that doing so will put the possible - * changes contained in the workspace to be rebased into a different context and thus might lead to unintended - * results when being published. - * - * @param string $workspace Name of the workspace to rebase, for example "user-john" - * @param string $baseWorkspace Name of the new base workspace - * @return void + * Rebase all outdated content streams */ - public function rebaseCommand($workspace, $baseWorkspace, string $contentRepositoryIdentifier = 'default') + public function rebaseOutdatedCommand(string $contentRepositoryIdentifier = 'default'): void { - throw new \BadMethodCallException( - 'Workspace rebasing is now a different concept ("real", git-like rebase <3),' - . ' changing the base workspace is not yet supported', - 1651960852 + $contentRepositoryId = ContentRepositoryId::fromString($contentRepositoryIdentifier); + $workspaceMaintenanceService = $this->contentRepositoryRegistry->buildService( + $contentRepositoryId, + new WorkspaceMaintenanceServiceFactory() ); - /* - $workspaceName = $workspace; - $workspace = $this->workspaceFinder->findOneByName(WorkspaceName::fromString($workspaceName)); - if (!$workspace instanceof Workspace) { - $this->outputLine('Workspace "%s" does not exist', [$workspaceName]); - $this->quit(1); - } + $outdatedWorkspaces = $workspaceMaintenanceService->rebaseOutdatedWorkspaces(); - if ($workspace->getName() === 'live') { - $this->outputLine('The workspace "live" cannot be rebased as it is the global base workspace.'); - $this->quit(2); - } - - $baseWorkspaceName = $baseWorkspace; - $baseWorkspace = $this->workspaceFinder->findOneByName($baseWorkspaceName); - if (!$baseWorkspace instanceof Workspace) { - $this->outputLine('The base workspace "%s" does not exist', [$baseWorkspaceName]); - $this->quit(2); + if (!count($outdatedWorkspaces)) { + $this->outputLine('There are no outdated workspaces.'); + } else { + foreach ($outdatedWorkspaces as $outdatedWorkspace) { + $this->outputFormatted('Rebased workspace %s', [$outdatedWorkspace->workspaceName->value]); + } } - - $workspace->setBaseWorkspace($baseWorkspace); - $this->workspaceFinder->update($workspace); - - $this->outputLine('Set "%s" as the new base workspace for "%s".', [$baseWorkspaceName, $workspaceName]); - */ } /** * Display a list of existing workspaces * - * @return void + * @throws StopCommandException */ - public function listCommand(string $contentRepositoryIdentifier = 'default') + public function listCommand(string $contentRepositoryIdentifier = 'default'): void { $contentRepositoryId = ContentRepositoryId::fromString($contentRepositoryIdentifier); $contentRepository = $this->contentRepositoryRegistry->get($contentRepositoryId); @@ -352,16 +314,18 @@ public function listCommand(string $contentRepositoryIdentifier = 'default') } $tableRows = []; - $headerRow = ['Name', 'Base Workspace', 'Title', 'Owner', 'Description']; + $headerRow = ['Name', 'Base Workspace', 'Title', 'Owner', 'Description', 'Status', 'Content Stream']; foreach ($workspaces as $workspace) { /* @var Workspace $workspace */ $tableRows[] = [ - $workspace->workspaceName, - $workspace->baseWorkspaceName ?: '', - $workspace->workspaceTitle, + $workspace->workspaceName->value, + $workspace->baseWorkspaceName?->value ?: '', + $workspace->workspaceTitle?->value, $workspace->workspaceOwner ?: '', - $workspace->workspaceDescription + $workspace->workspaceDescription->value, + $workspace->status->value, + $workspace->currentContentStreamId->value, ]; } $this->output->outputTable($tableRows, $headerRow);