diff --git a/src/Illuminate/Cache/Console/CacheTableCommand.php b/src/Illuminate/Cache/Console/CacheTableCommand.php index ab7b2d613b06..5002e401fa83 100644 --- a/src/Illuminate/Cache/Console/CacheTableCommand.php +++ b/src/Illuminate/Cache/Console/CacheTableCommand.php @@ -5,7 +5,7 @@ use Illuminate\Console\MigrationGeneratorCommand; use Symfony\Component\Console\Attribute\AsCommand; -#[AsCommand(name: 'make:cache-table')] +#[AsCommand(name: 'make:cache-table', aliases: ['cache:table'])] class CacheTableCommand extends MigrationGeneratorCommand { /** diff --git a/src/Illuminate/Console/Application.php b/src/Illuminate/Console/Application.php index 9bfe73b9b43e..303493492e4e 100755 --- a/src/Illuminate/Console/Application.php +++ b/src/Illuminate/Console/Application.php @@ -238,7 +238,9 @@ protected function addToParent(SymfonyCommand $command) public function resolve($command) { if (is_subclass_of($command, SymfonyCommand::class) && ($commandName = $command::getDefaultName())) { - $this->commandMap[$commandName] = $command; + foreach (explode('|', $commandName) as $name) { + $this->commandMap[$name] = $command; + } return null; } diff --git a/src/Illuminate/Console/Scheduling/ScheduleClearCacheCommand.php b/src/Illuminate/Console/Scheduling/ScheduleClearCacheCommand.php index 3deb1c6bcfda..10663695fa32 100644 --- a/src/Illuminate/Console/Scheduling/ScheduleClearCacheCommand.php +++ b/src/Illuminate/Console/Scheduling/ScheduleClearCacheCommand.php @@ -3,7 +3,9 @@ namespace Illuminate\Console\Scheduling; use Illuminate\Console\Command; +use Symfony\Component\Console\Attribute\AsCommand; +#[AsCommand(name: 'schedule:clear-cache')] class ScheduleClearCacheCommand extends Command { /** diff --git a/src/Illuminate/Database/Console/DbCommand.php b/src/Illuminate/Database/Console/DbCommand.php index dce6bc32dd17..b7561e08277f 100644 --- a/src/Illuminate/Database/Console/DbCommand.php +++ b/src/Illuminate/Database/Console/DbCommand.php @@ -4,9 +4,11 @@ use Illuminate\Console\Command; use Illuminate\Support\ConfigurationUrlParser; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Process\Process; use UnexpectedValueException; +#[AsCommand(name: 'db')] class DbCommand extends Command { /** diff --git a/src/Illuminate/Database/Console/Migrations/FreshCommand.php b/src/Illuminate/Database/Console/Migrations/FreshCommand.php index f18036f72a15..41d75ade559f 100644 --- a/src/Illuminate/Database/Console/Migrations/FreshCommand.php +++ b/src/Illuminate/Database/Console/Migrations/FreshCommand.php @@ -6,8 +6,10 @@ use Illuminate\Console\ConfirmableTrait; use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Database\Events\DatabaseRefreshed; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputOption; +#[AsCommand(name: 'migrate:fresh')] class FreshCommand extends Command { use ConfirmableTrait; diff --git a/src/Illuminate/Database/Console/Migrations/InstallCommand.php b/src/Illuminate/Database/Console/Migrations/InstallCommand.php index 901a83babb30..144ff512671b 100755 --- a/src/Illuminate/Database/Console/Migrations/InstallCommand.php +++ b/src/Illuminate/Database/Console/Migrations/InstallCommand.php @@ -4,8 +4,10 @@ use Illuminate\Console\Command; use Illuminate\Database\Migrations\MigrationRepositoryInterface; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputOption; +#[AsCommand(name: 'migrate:install')] class InstallCommand extends Command { /** diff --git a/src/Illuminate/Database/Console/Migrations/MigrateCommand.php b/src/Illuminate/Database/Console/Migrations/MigrateCommand.php index 12cab1eb1032..2b07dc94a540 100755 --- a/src/Illuminate/Database/Console/Migrations/MigrateCommand.php +++ b/src/Illuminate/Database/Console/Migrations/MigrateCommand.php @@ -10,10 +10,12 @@ use Illuminate\Database\SQLiteDatabaseDoesNotExistException; use Illuminate\Database\SqlServerConnection; use PDOException; +use Symfony\Component\Console\Attribute\AsCommand; use Throwable; use function Laravel\Prompts\confirm; +#[AsCommand(name: 'migrate')] class MigrateCommand extends BaseCommand implements Isolatable { use ConfirmableTrait; diff --git a/src/Illuminate/Database/Console/Migrations/MigrateMakeCommand.php b/src/Illuminate/Database/Console/Migrations/MigrateMakeCommand.php index 598334836101..367f14839e64 100644 --- a/src/Illuminate/Database/Console/Migrations/MigrateMakeCommand.php +++ b/src/Illuminate/Database/Console/Migrations/MigrateMakeCommand.php @@ -6,7 +6,9 @@ use Illuminate\Database\Migrations\MigrationCreator; use Illuminate\Support\Composer; use Illuminate\Support\Str; +use Symfony\Component\Console\Attribute\AsCommand; +#[AsCommand(name: 'make:migration')] class MigrateMakeCommand extends BaseCommand implements PromptsForMissingInput { /** diff --git a/src/Illuminate/Database/Console/Migrations/RefreshCommand.php b/src/Illuminate/Database/Console/Migrations/RefreshCommand.php index 5dff6467ac79..e348f1923fb3 100755 --- a/src/Illuminate/Database/Console/Migrations/RefreshCommand.php +++ b/src/Illuminate/Database/Console/Migrations/RefreshCommand.php @@ -6,8 +6,10 @@ use Illuminate\Console\ConfirmableTrait; use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Database\Events\DatabaseRefreshed; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputOption; +#[AsCommand(name: 'migrate:refresh')] class RefreshCommand extends Command { use ConfirmableTrait; diff --git a/src/Illuminate/Database/Console/Migrations/ResetCommand.php b/src/Illuminate/Database/Console/Migrations/ResetCommand.php index c5952fa0532a..dd9f05126e0a 100755 --- a/src/Illuminate/Database/Console/Migrations/ResetCommand.php +++ b/src/Illuminate/Database/Console/Migrations/ResetCommand.php @@ -4,8 +4,10 @@ use Illuminate\Console\ConfirmableTrait; use Illuminate\Database\Migrations\Migrator; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputOption; +#[AsCommand(name: 'migrate:reset')] class ResetCommand extends BaseCommand { use ConfirmableTrait; diff --git a/src/Illuminate/Database/Console/Migrations/RollbackCommand.php b/src/Illuminate/Database/Console/Migrations/RollbackCommand.php index b9385bcaa0cd..0a88ec5a1a06 100755 --- a/src/Illuminate/Database/Console/Migrations/RollbackCommand.php +++ b/src/Illuminate/Database/Console/Migrations/RollbackCommand.php @@ -4,8 +4,10 @@ use Illuminate\Console\ConfirmableTrait; use Illuminate\Database\Migrations\Migrator; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputOption; +#[AsCommand('migrate:rollback')] class RollbackCommand extends BaseCommand { use ConfirmableTrait; diff --git a/src/Illuminate/Database/Console/Migrations/StatusCommand.php b/src/Illuminate/Database/Console/Migrations/StatusCommand.php index 2dc1241bf940..9c4513b37716 100644 --- a/src/Illuminate/Database/Console/Migrations/StatusCommand.php +++ b/src/Illuminate/Database/Console/Migrations/StatusCommand.php @@ -4,8 +4,10 @@ use Illuminate\Database\Migrations\Migrator; use Illuminate\Support\Collection; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputOption; +#[AsCommand(name: 'migrate:status')] class StatusCommand extends BaseCommand { /** diff --git a/src/Illuminate/Database/Console/PruneCommand.php b/src/Illuminate/Database/Console/PruneCommand.php index 23875d1187b9..dc380b35a730 100644 --- a/src/Illuminate/Database/Console/PruneCommand.php +++ b/src/Illuminate/Database/Console/PruneCommand.php @@ -12,8 +12,10 @@ use Illuminate\Database\Events\ModelsPruned; use Illuminate\Support\Str; use InvalidArgumentException; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Finder\Finder; +#[AsCommand(name: 'model:prune')] class PruneCommand extends Command { /** diff --git a/src/Illuminate/Notifications/Console/NotificationTableCommand.php b/src/Illuminate/Notifications/Console/NotificationTableCommand.php index d2329f914620..d5cf329fe758 100644 --- a/src/Illuminate/Notifications/Console/NotificationTableCommand.php +++ b/src/Illuminate/Notifications/Console/NotificationTableCommand.php @@ -5,7 +5,7 @@ use Illuminate\Console\MigrationGeneratorCommand; use Symfony\Component\Console\Attribute\AsCommand; -#[AsCommand(name: 'make:notifications-table')] +#[AsCommand(name: 'make:notifications-table', aliases: ['notifications:table'])] class NotificationTableCommand extends MigrationGeneratorCommand { /** diff --git a/src/Illuminate/Queue/Console/BatchesTableCommand.php b/src/Illuminate/Queue/Console/BatchesTableCommand.php index aa9912429961..f68594e92823 100644 --- a/src/Illuminate/Queue/Console/BatchesTableCommand.php +++ b/src/Illuminate/Queue/Console/BatchesTableCommand.php @@ -7,7 +7,7 @@ use function Illuminate\Filesystem\join_paths; -#[AsCommand(name: 'make:queue-batches-table')] +#[AsCommand(name: 'make:queue-batches-table', aliases: ['queue:batches-table'])] class BatchesTableCommand extends MigrationGeneratorCommand { /** diff --git a/src/Illuminate/Queue/Console/FailedTableCommand.php b/src/Illuminate/Queue/Console/FailedTableCommand.php index b8fe04ad7520..f29736cc49dd 100644 --- a/src/Illuminate/Queue/Console/FailedTableCommand.php +++ b/src/Illuminate/Queue/Console/FailedTableCommand.php @@ -7,7 +7,7 @@ use function Illuminate\Filesystem\join_paths; -#[AsCommand(name: 'make:queue-failed-table')] +#[AsCommand(name: 'make:queue-failed-table', aliases: ['queue:failed-table'])] class FailedTableCommand extends MigrationGeneratorCommand { /** diff --git a/src/Illuminate/Queue/Console/TableCommand.php b/src/Illuminate/Queue/Console/TableCommand.php index a1bc6a90bc8b..a9336420c1db 100644 --- a/src/Illuminate/Queue/Console/TableCommand.php +++ b/src/Illuminate/Queue/Console/TableCommand.php @@ -7,7 +7,7 @@ use function Illuminate\Filesystem\join_paths; -#[AsCommand(name: 'make:queue-table')] +#[AsCommand(name: 'make:queue-table', aliases: ['queue:table'])] class TableCommand extends MigrationGeneratorCommand { /** diff --git a/src/Illuminate/Session/Console/SessionTableCommand.php b/src/Illuminate/Session/Console/SessionTableCommand.php index dda47dafe901..7718b117f5c4 100644 --- a/src/Illuminate/Session/Console/SessionTableCommand.php +++ b/src/Illuminate/Session/Console/SessionTableCommand.php @@ -7,7 +7,7 @@ use function Illuminate\Filesystem\join_paths; -#[AsCommand(name: 'make:session-table')] +#[AsCommand(name: 'make:session-table', aliases: ['session:table'])] class SessionTableCommand extends MigrationGeneratorCommand { /** diff --git a/tests/Console/ConsoleApplicationTest.php b/tests/Console/ConsoleApplicationTest.php index d58644539ab3..9edc18accf65 100755 --- a/tests/Console/ConsoleApplicationTest.php +++ b/tests/Console/ConsoleApplicationTest.php @@ -6,10 +6,15 @@ use Illuminate\Console\Command; use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Contracts\Foundation\Application as ApplicationContract; +use Illuminate\Events\Dispatcher as EventsDispatcher; +use Illuminate\Foundation\Application as FoundationApplication; use Illuminate\Tests\Console\Fixtures\FakeCommandWithInputPrompting; use Mockery as m; use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command as SymfonyCommand; +use Symfony\Component\Console\Exception\CommandNotFoundException; +use Throwable; class ConsoleApplicationTest extends TestCase { @@ -51,6 +56,68 @@ public function testResolveAddsCommandViaApplicationResolution() $this->assertEquals($command, $result); } + public function testResolvingCommandsWithAliasViaAttribute() + { + $container = new FoundationApplication(); + $app = new Application($container, new EventsDispatcher($container), $container->version()); + $app->resolve(CommandWithAliasViaAttribute::class); + $app->setContainerCommandLoader(); + + $this->assertInstanceOf(CommandWithAliasViaAttribute::class, $app->get('command-name')); + $this->assertInstanceOf(CommandWithAliasViaAttribute::class, $app->get('command-alias')); + $this->assertArrayHasKey('command-name', $app->all()); + $this->assertArrayHasKey('command-alias', $app->all()); + } + + public function testResolvingCommandsWithAliasViaProperty() + { + $container = new FoundationApplication(); + $app = new Application($container, new EventsDispatcher($container), $container->version()); + $app->resolve(CommandWithAliasViaProperty::class); + $app->setContainerCommandLoader(); + + $this->assertInstanceOf(CommandWithAliasViaProperty::class, $app->get('command-name')); + $this->assertInstanceOf(CommandWithAliasViaProperty::class, $app->get('command-alias')); + $this->assertArrayHasKey('command-name', $app->all()); + $this->assertArrayHasKey('command-alias', $app->all()); + } + + public function testResolvingCommandsWithNoAliasViaAttribute() + { + $container = new FoundationApplication(); + $app = new Application($container, new EventsDispatcher($container), $container->version()); + $app->resolve(CommandWithNoAliasViaAttribute::class); + $app->setContainerCommandLoader(); + + $this->assertInstanceOf(CommandWithNoAliasViaAttribute::class, $app->get('command-name')); + try { + $app->get('command-alias'); + $this->fail(); + } catch (Throwable $e) { + $this->assertInstanceOf(CommandNotFoundException::class, $e); + } + $this->assertArrayHasKey('command-name', $app->all()); + $this->assertArrayNotHasKey('command-alias', $app->all()); + } + + public function testResolvingCommandsWithNoAliasViaProperty() + { + $container = new FoundationApplication(); + $app = new Application($container, new EventsDispatcher($container), $container->version()); + $app->resolve(CommandWithNoAliasViaProperty::class); + $app->setContainerCommandLoader(); + + $this->assertInstanceOf(CommandWithNoAliasViaProperty::class, $app->get('command-name')); + try { + $app->get('command-alias'); + $this->fail(); + } catch (Throwable $e) { + $this->assertInstanceOf(CommandNotFoundException::class, $e); + } + $this->assertArrayHasKey('command-name', $app->all()); + $this->assertArrayNotHasKey('command-alias', $app->all()); + } + public function testCallFullyStringCommandLine() { $app = new Application( @@ -124,3 +191,25 @@ protected function getMockConsole(array $methods) ])->getMock(); } } + +#[AsCommand('command-name')] +class CommandWithNoAliasViaAttribute extends Command +{ + // +} +#[AsCommand('command-name', aliases: ['command-alias'])] +class CommandWithAliasViaAttribute extends Command +{ + // +} + +class CommandWithNoAliasViaProperty extends Command +{ + public $name = 'command-name'; +} + +class CommandWithAliasViaProperty extends Command +{ + public $name = 'command-name'; + public $aliases = ['command-alias']; +}