From 55351223d2bfc75fdfdf38e2357f75c313303601 Mon Sep 17 00:00:00 2001 From: Sergei Tigrov Date: Mon, 16 Oct 2023 18:55:31 +0700 Subject: [PATCH] Actualize option --all and --limit (#212) --- src/Command/DownCommand.php | 35 +++++++++-------- src/Command/HistoryCommand.php | 31 ++++++++------- src/Command/NewCommand.php | 22 +++++++---- src/Command/RedoCommand.php | 24 +++++++----- src/Command/UpdateCommand.php | 38 ++++++++++--------- .../Command/AbstractDownCommandTest.php | 2 +- .../Command/AbstractHistoryCommandTest.php | 30 ++++++++++++++- .../Common/Command/AbstractNewCommandTest.php | 30 ++++++++++++++- .../Command/AbstractRedoCommandTest.php | 34 +++++++++++++++-- .../Command/AbstractUpdateCommandTest.php | 13 +++++++ 10 files changed, 187 insertions(+), 72 deletions(-) diff --git a/src/Command/DownCommand.php b/src/Command/DownCommand.php index 3c2439da..900be35f 100644 --- a/src/Command/DownCommand.php +++ b/src/Command/DownCommand.php @@ -23,12 +23,12 @@ /** * Reverts the specified number of latest migrations. * - * For example, + * For example: * - * ``` - * yii migrate:down # revert the last migration - * yii migrate:down 3 # revert the last 3 migrations - * yii migrate:down all # revert all migrations + * ```shell + * ./yii migrate:down # revert the last migration + * ./yii migrate:down --limit=3 # revert the last 3 migrations + * ./yii migrate:down --all # revert all migrations * ``` */ #[AsCommand('migrate:down', 'Reverts the specified number of latest migrations.')] @@ -48,7 +48,7 @@ public function __construct( protected function configure(): void { $this - ->addOption('limit', 'l', InputOption::VALUE_OPTIONAL, 'Number of migrations to revert.', 1) + ->addOption('limit', 'l', InputOption::VALUE_REQUIRED, 'Number of migrations to revert.', 1) ->addOption('all', 'a', InputOption::VALUE_NONE, 'Revert all migrations.'); } @@ -61,14 +61,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int $this->migrationService->before(self::getDefaultName() ?? ''); - $limit = null; - if (!$input->getOption('all')) { - $limit = (int)$input->getOption('limit'); - if ($limit <= 0) { - $io->error('The limit argument must be greater than 0.'); - $this->migrationService->databaseConnection(); - return Command::INVALID; - } + $limit = !$input->getOption('all') + ? (int)$input->getOption('limit') + : null; + + if ($limit !== null && $limit <= 0) { + $io->error('The limit option must be greater than 0.'); + $this->migrationService->databaseConnection(); + + return Command::INVALID; } $migrations = $this->migrator->getHistory($limit); @@ -83,8 +84,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int $migrations = array_keys($migrations); $n = count($migrations); + $migrationWord = $n === 1 ? 'migration' : 'migrations'; + $output->writeln( - "Total $n " . ($n === 1 ? 'migration' : 'migrations') . " to be reverted:\n" + "Total $n $migrationWord to be reverted:\n" ); foreach ($migrations as $migration) { @@ -95,7 +98,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $helper = $this->getHelper('question'); $question = new ConfirmationQuestion( - "\nRevert the above " . ($n === 1 ? 'migration y/n: ' : 'migrations y/n: '), + "\nRevert the above $migrationWord y/n: ", true ); diff --git a/src/Command/HistoryCommand.php b/src/Command/HistoryCommand.php index eb54afec..2ddc0b8c 100644 --- a/src/Command/HistoryCommand.php +++ b/src/Command/HistoryCommand.php @@ -19,13 +19,14 @@ /** * Displays the migration history. * - * This command will show the list of migrations that have been applied - * so far. For example, + * This command will show the list of migrations that have been applied so far. * - * ``` - * yii migrate:history # last 10 migrations - * yii migrate:history 5 # last 5 migrations - * yii migrate:history all # whole history + * For example: + * + * ```shell + * ./yii migrate:history # last 10 migrations + * ./yii migrate:history --limit=5 # last 5 migrations + * ./yii migrate:history --all # whole history * ``` */ #[AsCommand('migrate:history', 'Displays the migration history.')] @@ -40,7 +41,9 @@ public function __construct( protected function configure(): void { - $this->addOption('limit', 'l', InputOption::VALUE_OPTIONAL, 'Maximum number of migrations to display.', null); + $this + ->addOption('limit', 'l', InputOption::VALUE_REQUIRED, 'Number of migrations to display.', 10) + ->addOption('all', 'a', InputOption::VALUE_NONE, 'All migrations.'); } protected function execute(InputInterface $input, OutputInterface $output): int @@ -51,10 +54,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int $this->migrationService->before(self::getDefaultName() ?? ''); - $limit = filter_var($input->getOption('limit'), FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE); + $limit = !$input->getOption('all') + ? (int)$input->getOption('limit') + : null; - if ($limit < 0) { - $io->error('The step argument must be greater than 0.'); + if ($limit !== null && $limit <= 0) { + $io->error('The limit option must be greater than 0.'); $this->migrationService->databaseConnection(); return Command::INVALID; @@ -70,12 +75,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int $n = count($migrations); - if ($limit > 0) { + if ($limit === $n) { $io->section("Last $n applied " . ($n === 1 ? 'migration' : 'migrations') . ':'); } else { - $io->section( - "Total $n " . ($n === 1 ? 'migration has' : 'migrations have') . ' been applied before:' - ); + $io->section("Total $n " . ($n === 1 ? 'migration has' : 'migrations have') . ' been applied before:'); } foreach ($migrations as $version => $time) { diff --git a/src/Command/NewCommand.php b/src/Command/NewCommand.php index 8a3257f4..8b736cb9 100644 --- a/src/Command/NewCommand.php +++ b/src/Command/NewCommand.php @@ -18,12 +18,13 @@ * Displays not yet applied migrations. * * This command will show the new migrations that have not been applied yet. - * For example, + * + * For example: * * ```shell * ./yii migrate:new # first 10 new migrations - * ./yii migrate:new 5 # first 5 new migrations - * ./yii migrate:new all # all new migrations + * ./yii migrate:new --limit=5 # first 5 new migrations + * ./yii migrate:new --all # all new migrations * ./yii migrate:new --path=@vendor/yiisoft/rbac-db/migrations # new migrations from the directory * ./yii migrate:new --namespace=Yiisoft\\Rbac\\Db\\Migrations # new migrations from the namespace * @@ -43,7 +44,8 @@ public function __construct(private MigrationService $migrationService) protected function configure(): void { $this - ->addOption('limit', 'l', InputOption::VALUE_OPTIONAL, 'Number of migrations to display.', '10') + ->addOption('limit', 'l', InputOption::VALUE_REQUIRED, 'Number of migrations to display.', 10) + ->addOption('all', 'a', InputOption::VALUE_NONE, 'All new migrations.') ->addOption('path', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Path to migrations to display.') ->addOption('namespace', 'ns', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Namespace of migrations to display.'); } @@ -66,10 +68,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int $this->migrationService->before(self::getDefaultName() ?? ''); - $limit = (int) $input->getOption('limit'); + $limit = !$input->getOption('all') + ? (int)$input->getOption('limit') + : null; - if ($limit < 0) { - $io->error('The step argument must be greater than 0.'); + if ($limit !== null && $limit <= 0) { + $io->error('The limit option must be greater than 0.'); $this->migrationService->databaseConnection(); return Command::INVALID; @@ -88,7 +92,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int $n = count($migrations); $migrationWord = $n === 1 ? 'migration' : 'migrations'; - if ($limit && $n > $limit) { + if ($limit !== null && $n > $limit) { + $migrations = array_slice($migrations, 0, $limit); + $io->warning("Showing $limit out of $n new $migrationWord:\n"); } else { $io->section("Found $n new $migrationWord:"); diff --git a/src/Command/RedoCommand.php b/src/Command/RedoCommand.php index 4452c7b1..eaf680f3 100644 --- a/src/Command/RedoCommand.php +++ b/src/Command/RedoCommand.php @@ -25,13 +25,14 @@ /** * Redoes the last few migrations. * - * This command will first revert the specified migrations, and then apply - * them again. For example, + * This command will first revert the specified migrations, and then apply them again. * - * ``` - * yii migrate:redo # redo the last applied migration - * yii migrate:redo 3 # redo last 3 applied migrations - * yii migrate:redo all # redo all migrations + * For example: + * + * ```shell + * ./yii migrate:redo # redo the last applied migration + * ./yii migrate:redo --limit=3 # redo last 3 applied migrations + * ./yii migrate:redo --all # redo all migrations * ``` */ #[AsCommand('migrate:redo', 'Redoes the last few migrations.')] @@ -52,7 +53,8 @@ public function __construct( protected function configure(): void { $this - ->addOption('limit', 'l', InputOption::VALUE_OPTIONAL, 'Number of migrations to redo.', null); + ->addOption('limit', 'l', InputOption::VALUE_REQUIRED, 'Number of migrations to redo.', 1) + ->addOption('all', 'a', InputOption::VALUE_NONE, 'All migrations.'); } protected function execute(InputInterface $input, OutputInterface $output): int @@ -65,10 +67,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int $this->migrationService->before(self::getDefaultName() ?? ''); - $limit = filter_var($input->getOption('limit'), FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE); + $limit = !$input->getOption('all') + ? (int)$input->getOption('limit') + : null; - if ($limit < 0) { - $io->error('The step argument must be greater than 0.'); + if ($limit !== null && $limit <= 0) { + $io->error('The limit option must be greater than 0.'); $this->migrationService->databaseConnection(); return Command::INVALID; diff --git a/src/Command/UpdateCommand.php b/src/Command/UpdateCommand.php index 6f1ad392..43ae2174 100644 --- a/src/Command/UpdateCommand.php +++ b/src/Command/UpdateCommand.php @@ -33,8 +33,8 @@ * ./yii migrate:up --namespace=Yiisoft\\Rbac\\Db\\Migrations # apply new migrations from the namespace * * # apply new migrations from multiple directories and namespaces - * ./yii migrate:new --path=@vendor/yiisoft/rbac-db/migrations --path=@vendor/yiisoft/cache-db/migrations - * ./yii migrate:new --namespace=Yiisoft\\Rbac\\Db\\Migrations --namespace=Yiisoft\\Cache\\Db\\Migrations + * ./yii migrate:up --path=@vendor/yiisoft/rbac-db/migrations --path=@vendor/yiisoft/cache-db/migrations + * ./yii migrate:up --namespace=Yiisoft\\Rbac\\Db\\Migrations --namespace=Yiisoft\\Cache\\Db\\Migrations * ``` */ #[AsCommand('migrate:up', 'Applies new migrations.')] @@ -52,7 +52,7 @@ public function __construct( protected function configure(): void { $this - ->addOption('limit', 'l', InputOption::VALUE_OPTIONAL, 'Number of migrations to apply.', '0') + ->addOption('limit', 'l', InputOption::VALUE_REQUIRED, 'Number of migrations to apply.') ->addOption('path', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Path to migrations to apply.') ->addOption('namespace', 'ns', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Namespace of migrations to apply.'); } @@ -79,7 +79,18 @@ protected function execute(InputInterface $input, OutputInterface $output): int return Command::INVALID; } - $limit = (int) $input->getOption('limit'); + $limit = $input->getOption('limit'); + + if ($limit !== null) { + $limit = (int)$limit; + + if ($limit <= 0) { + $io->error('The limit option must be greater than 0.'); + $this->migrationService->databaseConnection(); + + return Command::INVALID; + } + } /** @psalm-var class-string[] $migrations */ $migrations = $this->migrationService->getNewMigrations(); @@ -92,24 +103,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int return Command::SUCCESS; } - $total = count($migrations); + $n = count($migrations); + $migrationWord = $n === 1 ? 'migration' : 'migrations'; - if ($limit > 0) { + if ($limit !== null && $n > $limit) { $migrations = array_slice($migrations, 0, $limit); - } - - $n = count($migrations); - if ($n === $total) { - $output->writeln( - "Total $n new " . ($n === 1 ? 'migration' : 'migrations') . ' to be ' . - "applied:\n" - ); + $output->writeln("Total $limit out of $n new $migrationWord to be applied:\n"); } else { - $output->writeln( - "Total $n out of $total new " . ($total === 1 ? 'migration' : 'migrations') . - " to be applied:\n" - ); + $output->writeln("Total $n new $migrationWord to be applied:\n"); } foreach ($migrations as $migration) { diff --git a/tests/Common/Command/AbstractDownCommandTest.php b/tests/Common/Command/AbstractDownCommandTest.php index d31dfe62..8f61a565 100644 --- a/tests/Common/Command/AbstractDownCommandTest.php +++ b/tests/Common/Command/AbstractDownCommandTest.php @@ -270,7 +270,7 @@ public function testIncorrectLimit(int $limit): void $output = $command->getDisplay(true); $this->assertSame(Command::INVALID, $exitCode); - $this->assertStringContainsString('The limit argument must be greater than 0.', $output); + $this->assertStringContainsString('The limit option must be greater than 0.', $output); } public function createCommand(ContainerInterface $container): CommandTester diff --git a/tests/Common/Command/AbstractHistoryCommandTest.php b/tests/Common/Command/AbstractHistoryCommandTest.php index 36158e21..a863b138 100644 --- a/tests/Common/Command/AbstractHistoryCommandTest.php +++ b/tests/Common/Command/AbstractHistoryCommandTest.php @@ -93,7 +93,7 @@ public function testIncorrectLimit(): void $output = $command->getDisplay(true); $this->assertSame(Command::INVALID, $exitCode); - $this->assertStringContainsString('The step argument must be greater than 0.', $output); + $this->assertStringContainsString('The limit option must be greater than 0.', $output); } public function testWithoutNewMigrations(): void @@ -109,6 +109,34 @@ public function testWithoutNewMigrations(): void $this->assertStringContainsString('[WARNING] No migration has been done before.', $output); } + public function testOptionAll(): void + { + MigrationHelper::useMigrationsNamespace($this->container); + + MigrationHelper::createAndApplyMigration( + $this->container, + 'Create_Post', + 'table', + 'post', + ['name:string(50)'], + ); + MigrationHelper::createAndApplyMigration( + $this->container, + 'Create_User', + 'table', + 'user', + ['name:string(50)'], + ); + + $command = $this->createCommand($this->container); + + $exitCode = $command->execute(['--all' => true]); + $output = $command->getDisplay(true); + + $this->assertSame(Command::SUCCESS, $exitCode); + $this->assertStringContainsString('Total 2 migrations have been applied before:', $output); + } + public function createCommand(ContainerInterface $container): CommandTester { return CommandHelper::getCommandTester($container, HistoryCommand::class); diff --git a/tests/Common/Command/AbstractNewCommandTest.php b/tests/Common/Command/AbstractNewCommandTest.php index 6ab81870..1cb9a3fe 100644 --- a/tests/Common/Command/AbstractNewCommandTest.php +++ b/tests/Common/Command/AbstractNewCommandTest.php @@ -103,7 +103,7 @@ public function testIncorrectLimit(): void $output = $command->getDisplay(true); $this->assertSame(Command::INVALID, $exitCode); - $this->assertStringContainsString('[ERROR] The step argument must be greater than 0.', $output); + $this->assertStringContainsString('[ERROR] The limit option must be greater than 0.', $output); $this->assertStringContainsString('Database connection: ' . $this->driverName, $output); } @@ -168,6 +168,34 @@ public function testCountMigrationsMoreLimit(): void $this->assertStringContainsString($classCreateUser, $output); } + public function testOptionAll(): void + { + MigrationHelper::useMigrationsNamespace($this->container); + + MigrationHelper::createMigration( + $this->container, + 'Create_Post', + 'table', + 'post', + ['name:string(50)'], + ); + MigrationHelper::createMigration( + $this->container, + 'Create_User', + 'table', + 'user', + ['name:string(50)'], + ); + + $command = $this->createCommand($this->container); + + $exitCode = $command->execute(['--all' => true]); + $output = $command->getDisplay(true); + + $this->assertSame(Command::SUCCESS, $exitCode); + $this->assertStringContainsString('Found 2 new migrations:', $output); + } + public function testOptionPath(): void { MigrationHelper::useMigrationsPath($this->container); diff --git a/tests/Common/Command/AbstractRedoCommandTest.php b/tests/Common/Command/AbstractRedoCommandTest.php index 8e6eb9c9..516062d6 100644 --- a/tests/Common/Command/AbstractRedoCommandTest.php +++ b/tests/Common/Command/AbstractRedoCommandTest.php @@ -48,7 +48,7 @@ public function testExecuteWithNamespace(): void $output = $command->getDisplay(true); $this->assertSame(Command::SUCCESS, $exitCode); - $this->assertStringContainsString('2 migrations were redone.', $output); + $this->assertStringContainsString('1 migration was redone.', $output); $this->assertStringContainsString('Migration redone successfully.', $output); $this->assertExistsTables($this->container, 'post', 'user'); } @@ -79,7 +79,7 @@ public function testExecuteWithPath(): void $output = $command->getDisplay(true); $this->assertSame(Command::SUCCESS, $exitCode); - $this->assertStringContainsString('2 migrations were redone.', $output); + $this->assertStringContainsString('1 migration was redone.', $output); $this->assertStringContainsString('Migration redone successfully.', $output); $this->assertExistsTables($this->container, 'post', 'user'); } @@ -136,7 +136,7 @@ public function testIncorrectLimit(): void $output = $command->getDisplay(true); $this->assertSame(Command::INVALID, $exitCode); - $this->assertStringContainsString('The step argument must be greater than 0.', $output); + $this->assertStringContainsString('The limit option must be greater than 0.', $output); } public function testWithoutNewMigrations(): void @@ -169,6 +169,34 @@ public function testNotRevertibleMigrationInterface(): void $command->execute([]); } + public function testOptionAll(): void + { + MigrationHelper::useMigrationsNamespace($this->container); + + MigrationHelper::createAndApplyMigration( + $this->container, + 'Create_Post', + 'table', + 'post', + ['name:string(50)'], + ); + MigrationHelper::createAndApplyMigration( + $this->container, + 'Create_User', + 'table', + 'user', + ['name:string(50)'], + ); + + $command = $this->createCommand($this->container); + + $exitCode = $command->setInputs(['no'])->execute(['--all' => true]); + $output = $command->getDisplay(true); + + $this->assertSame(Command::SUCCESS, $exitCode); + $this->assertStringContainsString('Total 2 migrations to be redone:', $output); + } + public function createCommand(ContainerInterface $container): CommandTester { return CommandHelper::getCommandTester($container, RedoCommand::class); diff --git a/tests/Common/Command/AbstractUpdateCommandTest.php b/tests/Common/Command/AbstractUpdateCommandTest.php index f72b9f49..c9450ae3 100644 --- a/tests/Common/Command/AbstractUpdateCommandTest.php +++ b/tests/Common/Command/AbstractUpdateCommandTest.php @@ -403,6 +403,19 @@ public function testOptionNamespace(): void } } + public function testIncorrectLimit(): void + { + MigrationHelper::useMigrationsNamespace($this->container); + + $command = $this->createCommand($this->container); + + $exitCode = $command->execute(['-l' => -1]); + $output = $command->getDisplay(true); + + $this->assertSame(Command::INVALID, $exitCode); + $this->assertStringContainsString('[ERROR] The limit option must be greater than 0.', $output); + } + public function createCommand(ContainerInterface $container): CommandTester { return CommandHelper::getCommandTester($container, UpdateCommand::class);