diff --git a/CHANGELOG.md b/CHANGELOG.md
index bec501b6..00b526ef 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
- Enh #317: Explicitly import classes, functions, and constants in "use" section (@mspirkov)
- Enh #318: Remove unnecessary files from Composer package (@mspirkov)
+- Enh #319: Remove confirmation prompt from `migrate:create` command as creating a migration is non-destructive (@samdark)
## 2.0.1 December 20, 2025
diff --git a/src/Command/CreateCommand.php b/src/Command/CreateCommand.php
index dfea59af..1be367d7 100644
--- a/src/Command/CreateCommand.php
+++ b/src/Command/CreateCommand.php
@@ -6,12 +6,10 @@
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
-use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Style\SymfonyStyle;
use Yiisoft\Db\Migration\Migrator;
use Yiisoft\Db\Migration\Service\Generate\CreateService;
@@ -88,7 +86,6 @@ protected function configure(): void
->addOption('and', null, InputOption::VALUE_REQUIRED, 'And junction.')
->addOption('path', null, InputOption::VALUE_REQUIRED, 'Path to migration directory.')
->addOption('namespace', 'ns', InputOption::VALUE_REQUIRED, 'Migration file namespace.')
- ->addOption('force-yes', 'y', InputOption::VALUE_NONE, 'Force yes to all questions.')
->setHelp('This command generates new migration file.');
}
@@ -159,54 +156,34 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return Command::INVALID;
}
- if ($this->confirm($input, $output)) {
- /** @var string|null $fields */
- $fields = $input->getOption('fields');
- /** @var string|null $tableComment */
- $tableComment = $input->getOption('table-comment');
-
- $content = $this->createService->run(
- $command,
- $table,
- $className,
- $namespace,
- $fields,
- $and,
- $tableComment,
- );
+ /** @var string|null $fields */
+ $fields = $input->getOption('fields');
+ /** @var string|null $tableComment */
+ $tableComment = $input->getOption('table-comment');
+
+ $content = $this->createService->run(
+ $command,
+ $table,
+ $className,
+ $namespace,
+ $fields,
+ $and,
+ $tableComment,
+ );
- $file = $migrationPath . DIRECTORY_SEPARATOR . $className . '.php';
+ $file = $migrationPath . DIRECTORY_SEPARATOR . $className . '.php';
- file_put_contents($file, $content, LOCK_EX);
+ file_put_contents($file, $content, LOCK_EX);
- $output->writeln("\n\t$className");
- $output->writeln("\n");
- $io->success('New migration created successfully.');
- }
+ $output->writeln("\n\t$className");
+ $output->writeln("\n");
+ $io->success('New migration created successfully.');
$this->migrationService->databaseConnection();
return Command::SUCCESS;
}
- private function confirm(InputInterface $input, OutputInterface $output): bool
- {
- if ($input->getOption('force-yes')) {
- return true;
- }
-
- $question = new ConfirmationQuestion(
- "\nCreate new migration y/n: >",
- false,
- );
-
- /** @var QuestionHelper $helper */
- $helper = $this->getHelper('question');
-
- /** @var bool */
- return $helper->ask($input, $output, $question);
- }
-
private function generateName(string $command, string $name, ?string $and): string
{
$result = '';
diff --git a/src/MigrationBuilder.php b/src/MigrationBuilder.php
index 15ccead9..24e5abc3 100644
--- a/src/MigrationBuilder.php
+++ b/src/MigrationBuilder.php
@@ -18,6 +18,7 @@
use Yiisoft\Db\Migration\Informer\MigrationInformerInterface;
use Yiisoft\Db\Schema\Column\ColumnBuilder;
use Yiisoft\Db\Schema\Column\ColumnInterface;
+use Yiisoft\Db\Command\CommandInterface;
use function implode;
use function ltrim;
@@ -65,7 +66,7 @@ public function getDb(): ConnectionInterface
* @throws InvalidConfigException
* @throws NotSupportedException
*
- * @see \Yiisoft\Db\Command\CommandInterface::execute() for more details.
+ * @see CommandInterface::execute() for more details.
*/
public function execute(string $sql, array $params = []): void
{
diff --git a/tests/Common/Command/AbstractCreateCommandTest.php b/tests/Common/Command/AbstractCreateCommandTest.php
index 035fd7be..5a4ac47b 100644
--- a/tests/Common/Command/AbstractCreateCommandTest.php
+++ b/tests/Common/Command/AbstractCreateCommandTest.php
@@ -4,7 +4,6 @@
namespace Yiisoft\Db\Migration\Tests\Common\Command;
-use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;
use Psr\Container\ContainerInterface;
use Symfony\Component\Console\Command\Command;
@@ -30,7 +29,6 @@ public function testCreateTableWithPath(): void
$migrationsPath = MigrationHelper::useMigrationsPath($this->container);
$command = $this->createCommand($this->container);
- $command->setInputs(['yes']);
$exitCode = $command->execute(['name' => 'post', '--command' => 'table']);
$output = preg_replace('/(\R|\s)+/', ' ', $command->getDisplay(true));
@@ -71,7 +69,6 @@ public function down(MigrationBuilder \$b): void
$this->assertSame(Command::SUCCESS, $exitCode);
$this->assertStringContainsString($className, $output);
$this->assertStringContainsString('CreatePostTable', $output);
- $this->assertStringContainsString('Create new migration y/n:', $output);
$this->assertEqualsWithoutLE($expectedMigrationCode, $generatedMigrationCode);
$this->assertStringContainsString('[OK] New migration created successfully.', $output);
$this->assertStringContainsString('Database connection: ' . $this->driverName, $output);
@@ -82,7 +79,6 @@ public function testCreateTableWithNamespace(): void
$migrationsPath = MigrationHelper::useMigrationsNamespace($this->container);
$command = $this->createCommand($this->container);
- $command->setInputs(['yes']);
$exitCode = $command->execute(['name' => 'post', '--command' => 'table']);
$output = preg_replace('/(\R|\s)+/', ' ', $command->getDisplay(true));
@@ -124,7 +120,6 @@ public function down(MigrationBuilder \$b): void
$generatedMigrationCode = file_get_contents($migrationsPath . '/' . $className . '.php');
$this->assertSame(Command::SUCCESS, $exitCode);
- $this->assertStringContainsString('Create new migration y/n:', $output);
$this->assertEqualsWithoutLE($expectedMigrationCode, $generatedMigrationCode);
}
@@ -143,7 +138,6 @@ public function testCreateTableExtends(): void
);
$command = $this->createCommand($this->container);
- $command->setInputs(['yes']);
$exitCode = $command->execute([
'name' => 'post',
@@ -325,7 +319,6 @@ public function down(MigrationBuilder \$b): void
$generatedMigrationCode = file_get_contents($migrationsPath . '/' . $className . '.php');
$this->assertSame(Command::SUCCESS, $exitCode);
- $this->assertStringContainsString('Create new migration y/n:', $output);
$this->assertStringContainsString(
'Related table for field "category_id" exists, but primary key is composite. Default name "id" will be used for related field',
$output,
@@ -338,7 +331,6 @@ public function testWithoutTablePrefix(): void
$migrationsPath = MigrationHelper::useMigrationsNamespace($this->container);
$command = $this->createCommand($this->container);
- $command->setInputs(['yes']);
$command->execute(
[
@@ -431,7 +423,6 @@ public function testExecuteInputNamespaces(): void
$command = $this->createCommand($this->container);
foreach (['--namespace', '-ns'] as $option) {
- $command->setInputs(['yes']);
$exitCode = $command->execute(['name' => 'post', $option => MigrationHelper::NAMESPACE]);
$output = preg_replace('/(\R|\s)+/', ' ', $command->getDisplay(true));
@@ -466,7 +457,6 @@ public function down(MigrationBuilder \$b): void
$generatedMigrationCode = file_get_contents(MigrationHelper::getPathForMigrationNamespace() . '/' . $className . '.php');
$this->assertSame(Command::SUCCESS, $exitCode);
- $this->assertStringContainsString('Create new migration y/n:', $output);
$this->assertEqualsWithoutLE($expectedMigrationCode, $generatedMigrationCode);
}
}
@@ -477,13 +467,11 @@ public function testExecuteInputPath(): void
MigrationHelper::resetPathAndNamespace($this->container);
$command = $this->createCommand($this->container);
- $command->setInputs(['yes']);
$exitCode = $command->execute(['name' => 'post', '--path' => MigrationHelper::getRuntimePath()]);
$output = preg_replace('/(\R|\s)+/', ' ', $command->getDisplay(true));
$this->assertSame(Command::SUCCESS, $exitCode);
- $this->assertStringContainsString('Create new migration y/n:', $output);
$this->assertMatchesRegularExpression("/\s+M\d{12}Post/m", $output);
$this->assertStringContainsString('[OK] New migration created successfully.', $output);
$this->assertCount(1, FileHelper::findFiles($path));
@@ -494,7 +482,6 @@ public function testExecuteNameException(): void
MigrationHelper::useMigrationsNamespace($this->container);
$command = $this->createCommand($this->container);
- $command->setInputs(['yes']);
$exitCode = $command->execute(['name' => 'post?']);
$output = preg_replace('/(\R|\s)+/', ' ', $command->getDisplay(true));
@@ -511,7 +498,6 @@ public function testExecuteCommandException(): void
MigrationHelper::useMigrationsNamespace($this->container);
$command = $this->createCommand($this->container);
- $command->setInputs(['yes']);
$exitCode = $command->execute(['name' => 'post', '--command' => 'noExist']);
$output = preg_replace('/(\R|\s)+/', ' ', $command->getDisplay(true));
@@ -529,7 +515,6 @@ public function testExecuteNameToLongException(): void
MigrationHelper::useMigrationsNamespace($this->container);
$command = $this->createCommand($this->container);
- $command->setInputs(['yes']);
$exitCode = $command->execute([
'name' => str_repeat('x', 200),
@@ -545,7 +530,6 @@ public function testAddColumn(): void
$migrationsPath = MigrationHelper::useMigrationsNamespace($this->container);
$command = $this->createCommand($this->container);
- $command->setInputs(['yes']);
$exitCode = $command->execute(['name' => 'post', '--command' => 'addColumn', '--fields' => 'position:integer']);
$output = preg_replace('/(\R|\s)+/', ' ', $command->getDisplay(true));
@@ -583,7 +567,6 @@ public function down(MigrationBuilder \$b): void
$generatedMigrationCode = file_get_contents($migrationsPath . '/' . $className . '.php');
$this->assertSame(Command::SUCCESS, $exitCode);
- $this->assertStringContainsString('Create new migration y/n:', $output);
$this->assertEqualsWithoutLE($expectedMigrationCode, $generatedMigrationCode);
}
@@ -592,7 +575,6 @@ public function testDropColumn(): void
$migrationsPath = MigrationHelper::useMigrationsNamespace($this->container);
$command = $this->createCommand($this->container);
- $command->setInputs(['yes']);
$exitCode = $command->execute([
'name' => 'post',
@@ -634,7 +616,6 @@ public function down(MigrationBuilder \$b): void
$generatedMigrationCode = file_get_contents($migrationsPath . '/' . $className . '.php');
$this->assertSame(Command::SUCCESS, $exitCode);
- $this->assertStringContainsString('Create new migration y/n:', $output);
$this->assertEqualsWithoutLE($expectedMigrationCode, $generatedMigrationCode);
}
@@ -643,7 +624,6 @@ public function testDropTable(): void
$migrationsPath = MigrationHelper::useMigrationsNamespace($this->container);
$command = $this->createCommand($this->container);
- $command->setInputs(['yes']);
$exitCode = $command->execute(
[
@@ -693,7 +673,6 @@ public function down(MigrationBuilder \$b): void
$generatedMigrationCode = file_get_contents($migrationsPath . '/' . $className . '.php');
$this->assertSame(Command::SUCCESS, $exitCode);
- $this->assertStringContainsString('Create new migration y/n:', $output);
$this->assertEqualsWithoutLE($expectedMigrationCode, $generatedMigrationCode);
}
@@ -702,7 +681,6 @@ public function testCreateTableWithFields(): void
$migrationsPath = MigrationHelper::useMigrationsNamespace($this->container);
$command = $this->createCommand($this->container);
- $command->setInputs(['yes']);
$exitCode = $command->execute(
[
@@ -753,7 +731,6 @@ public function down(MigrationBuilder \$b): void
$generatedMigrationCode = file_get_contents($migrationsPath . '/' . $className . '.php');
$this->assertSame(Command::SUCCESS, $exitCode);
- $this->assertStringContainsString('Create new migration y/n:', $output);
$this->assertEqualsWithoutLE($expectedMigrationCode, $generatedMigrationCode);
}
@@ -762,7 +739,6 @@ public function testCreateTableWithFieldsForeignKey(): void
$migrationsPath = MigrationHelper::useMigrationsNamespace($this->container);
$command = $this->createCommand($this->container);
- $command->setInputs(['yes']);
$exitCode = $command->execute(
[
@@ -878,7 +854,6 @@ public function down(MigrationBuilder \$b): void
$generatedMigrationCode = file_get_contents($migrationsPath . '/' . $className . '.php');
$this->assertSame(Command::SUCCESS, $exitCode);
- $this->assertStringContainsString('Create new migration y/n:', $output);
$this->assertEqualsWithoutLE($expectedMigrationCode, $generatedMigrationCode);
}
@@ -887,7 +862,6 @@ public function testJunction(): void
$migrationsPath = MigrationHelper::useMigrationsNamespace($this->container);
$command = $this->createCommand($this->container);
- $command->setInputs(['yes']);
$exitCode = $command->execute(
[
@@ -1002,7 +976,6 @@ public function down(MigrationBuilder \$b): void
$generatedMigrationCode = file_get_contents($migrationsPath . '/' . $className . '.php');
$this->assertSame(Command::SUCCESS, $exitCode);
- $this->assertStringContainsString('Create new migration y/n:', $output);
$this->assertEqualsWithoutLE($expectedMigrationCode, $generatedMigrationCode);
}
@@ -1013,7 +986,6 @@ public function testIncorrectNewMigrationPath(): void
$this->container->get(MigrationService::class)->setNewMigrationPath(__DIR__ . '/not-exists');
$command = $this->createCommand($this->container);
- $command->setInputs(['yes']);
$exitCode = $command->execute(['name' => 'post']);
$output = preg_replace('/(\R|\s)+/', ' ', $command->getDisplay(true));
@@ -1029,7 +1001,6 @@ public function testWithoutNewMigrationPath(): void
$this->container->get(MigrationService::class)->setNewMigrationPath('');
$command = $this->createCommand($this->container);
- $command->setInputs(['yes']);
$exitCode = $command->execute(['name' => 'post']);
$output = preg_replace('/(\R|\s)+/', ' ', $command->getDisplay(true));
@@ -1049,7 +1020,6 @@ public function testIncorrectNewMigrationNamespace(): void
->setNewMigrationNamespace('Yiisoft\\Db\\Migration\\TestsRuntime\\NotExists');
$command = $this->createCommand($this->container);
- $command->setInputs(['yes']);
$exitCode = $command->execute(['name' => 'post']);
$output = preg_replace('/(\R|\s)+/', ' ', $command->getDisplay(true));
@@ -1065,7 +1035,6 @@ public function testWithoutNewMigrationNamespace(): void
$this->container->get(MigrationService::class)->setNewMigrationNamespace('');
$command = $this->createCommand($this->container);
- $command->setInputs(['yes']);
$exitCode = $command->execute(['name' => 'post']);
$output = preg_replace('/(\R|\s)+/', ' ', $command->getDisplay(true));
@@ -1083,7 +1052,6 @@ public function testWithNewMigrationPathAndNamespace(): void
MigrationHelper::useMigrationsNamespace($this->container);
$command = $this->createCommand($this->container);
- $command->setInputs(['yes']);
$exitCode = $command->execute(['name' => 'post']);
$output = preg_replace('/(\R|\s)+/', ' ', $command->getDisplay(true));
@@ -1098,7 +1066,6 @@ public function testWithNewMigrationPathAndNamespace(): void
public function testWithOptionsPathAndNamespace(): void
{
$command = $this->createCommand($this->container);
- $command->setInputs(['yes']);
$exitCode = $command->execute([
'name' => 'post',
@@ -1114,24 +1081,6 @@ public function testWithOptionsPathAndNamespace(): void
);
}
- #[TestWith(['--force-yes'])]
- #[TestWith(['-y'])]
- public function testForceYes(string $arg): void
- {
- $migrationsPath = MigrationHelper::useMigrationsNamespace($this->container);
-
- $command = $this->createCommand($this->container);
- $command->setInputs(['no']);
-
- $exitCode = $command->execute(['name' => 'post', $arg => true]);
-
- $output = preg_replace('/(\R|\s)+/', ' ', $command->getDisplay(true));
- $className = MigrationHelper::findMigrationClassNameInOutput($output);
-
- $this->assertSame(Command::SUCCESS, $exitCode);
- $this->assertFileExists($migrationsPath . '/' . $className . '.php');
- }
-
public function createCommand(ContainerInterface $container): CommandTester
{
return CommandHelper::getCommandTester($container, CreateCommand::class);