Skip to content

Commit

Permalink
[BUGFIX] Properly handle aliases with the AsCommand registration
Browse files Browse the repository at this point in the history
The auto configuration of the symfony AsCommand
attribute, introduced with  #101567, now properly
handles the `aliases` parameter.

Resolves: #102406
Related: #101567
Releases: main, 12.4
Change-Id: I4a872e28d041dcfd4bf65517e5d01c625da82af9
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/81777
Tested-by: Benjamin Franzke <ben@bnf.dev>
Tested-by: core-ci <typo3@b13.com>
Reviewed-by: Benjamin Franzke <ben@bnf.dev>
  • Loading branch information
o-ba authored and bnf committed Nov 20, 2023
1 parent b5d257e commit 30a49f8
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 6 deletions.
31 changes: 29 additions & 2 deletions typo3/sysext/core/Configuration/Services.php
Expand Up @@ -23,16 +23,43 @@
$containerBuilder->registerAttributeForAutoconfiguration(
AsCommand::class,
static function (ChildDefinition $definition, AsCommand $attribute): void {
$commands = explode('|', $attribute->name);
$hidden = false;
$name = array_shift($commands);

if ($name === '') {
// Symfony AsCommand attribute encodes hidden flag as an empty command name
$hidden = true;
$name = array_shift($commands);
}

if ($name === null) {
// This happens in case no name and no aliases are given
// @todo Throw exception
return;
}

$definition->addTag(
'console.command',
[
'command' => ltrim($attribute->name, '|'),
'command' => $name,
'description' => $attribute->description,
'hidden' => str_starts_with($attribute->name, '|'),
'hidden' => $hidden,
// The `schedulable` flag is not configurable via symfony attribute parameters, use sane defaults
'schedulable' => true,
]
);

foreach ($commands as $name) {
$definition->addTag(
'console.command',
[
'command' => $name,
'hidden' => $hidden,
'alias' => true,
]
);
}
}
);

Expand Down
Expand Up @@ -14,9 +14,10 @@ Description
The symfony PHP attribute :php:`\Symfony\Component\Console\Attribute\AsCommand`
is now accepted to register console commands.
This way CLI commands can be registered by setting the attribute on the command
class. Only the parameters `command`, `description` and `hidden` are still viable. In order to
overwrite the schedulable parameter use the old :file:`Services.yaml` way to
register console commands. By default `schedulable` is true.
class. Only the parameters `command`, `description`, `aliases` and `hidden` are
still viable. In order to overwrite the schedulable parameter use the old
:file:`Services.yaml` way to register console commands. By default `schedulable`
is true.

Before:

Expand All @@ -29,6 +30,9 @@ Before:
command: 'myprefix:dofoo'
description: 'My description'
schedulable: true
- name: 'console.command'
command: 'myprefix:dofoo-alias'
alias: true
After:

Expand All @@ -45,7 +49,7 @@ attribute is assigned to the command class instead:
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Attribute\AsCommand;
#[AsCommand(name: 'myprefix:dofoo', description: 'My description')]
#[AsCommand(name: 'myprefix:dofoo', description: 'My description', aliases: ['myprefix:dofoo-alias'])]
class MyCommand extends Command
{
}
Expand Down
Expand Up @@ -19,6 +19,7 @@

use TYPO3\CMS\Core\Console\CommandRegistry;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
use TYPO3Tests\TestDi\Command\AliasTestCommand;
use TYPO3Tests\TestDi\Command\HiddenTestCommand;
use TYPO3Tests\TestDi\Command\VisibleTestCommand;

Expand Down Expand Up @@ -54,6 +55,27 @@ public function asCommandHiddenAttributeIsRespected(): void
self::assertArrayNotHasKey('testdi:ascommand:hidden', $visibleList);
}

/**
* @test
*/
public function asCommandAliasAttributeIsRespected(): void
{
$commandRegistry = $this->get(CommandRegistry::class);
$visibleList = $commandRegistry->filter();

$aliasCommand = $commandRegistry->get('testdi:ascommand:alias-main');
$aliasSub1Command = $commandRegistry->get('testdi:ascommand:alias-sub1');
$aliasSub2Command = $commandRegistry->get('testdi:ascommand:alias-sub2');

self::assertInstanceOf(AliasTestCommand::class, $aliasCommand);
self::assertInstanceOf(AliasTestCommand::class, $aliasSub1Command);
self::assertInstanceOf(AliasTestCommand::class, $aliasSub2Command);

self::assertArrayHasKey('testdi:ascommand:alias-main', $visibleList);
self::assertArrayNotHasKey('testdi:ascommand:alias-sub1', $visibleList);
self::assertArrayNotHasKey('testdi:ascommand:alias-sub2', $visibleList);
}

/**
* @test
*/
Expand Down
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/

namespace TYPO3Tests\TestDi\Command;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

#[AsCommand(name: 'testdi:ascommand:alias-main', description: 'This is a alias command.', aliases: ['testdi:ascommand:alias-sub1', 'testdi:ascommand:alias-sub2'])]
class AliasTestCommand extends Command
{
protected function execute(InputInterface $input, OutputInterface $output): int
{
return Command::SUCCESS;
}
}

0 comments on commit 30a49f8

Please sign in to comment.