From 467385f1348ee84b1cc3ce201f7df433088ef82d Mon Sep 17 00:00:00 2001 From: Amir Hossein Date: Wed, 27 Aug 2025 00:13:08 +0330 Subject: [PATCH 1/3] Revert "Revert "[12.x] Add drop patterns support to `TableGuesser` for drop migrations (#56608)" (#56752)" This reverts commit b3433716d88a385394e52cfdb862d38a6a467121. --- .../Database/Console/Migrations/TableGuesser.php | 11 +++++++++++ tests/Database/TableGuesserTest.php | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/src/Illuminate/Database/Console/Migrations/TableGuesser.php b/src/Illuminate/Database/Console/Migrations/TableGuesser.php index 30bd53096e06..2c90387b06fc 100644 --- a/src/Illuminate/Database/Console/Migrations/TableGuesser.php +++ b/src/Illuminate/Database/Console/Migrations/TableGuesser.php @@ -14,6 +14,11 @@ class TableGuesser '/.+_(to|from|in)_(\w+)$/', ]; + const DROP_PATTERNS = [ + '/^drop_(\w+)_table$/', + '/^drop_(\w+)$/', + ]; + /** * Attempt to guess the table name and "creation" status of the given migration. * @@ -33,5 +38,11 @@ public static function guess($migration) return [$matches[2], $create = false]; } } + + foreach (self::DROP_PATTERNS as $pattern) { + if (preg_match($pattern, $migration, $matches)) { + return [$matches[1], $create = false]; + } + } } } diff --git a/tests/Database/TableGuesserTest.php b/tests/Database/TableGuesserTest.php index f983995e4dd5..d0a04c07d16f 100644 --- a/tests/Database/TableGuesserTest.php +++ b/tests/Database/TableGuesserTest.php @@ -28,6 +28,10 @@ public function testMigrationIsProperlyParsed() [$table, $create] = TableGuesser::guess('drop_status_column_from_users_table'); $this->assertSame('users', $table); $this->assertFalse($create); + + [$table, $create] = TableGuesser::guess('drop_users_table'); + $this->assertSame('users', $table); + $this->assertFalse($create); } public function testMigrationIsProperlyParsedWithoutTableSuffix() @@ -51,5 +55,9 @@ public function testMigrationIsProperlyParsedWithoutTableSuffix() [$table, $create] = TableGuesser::guess('drop_status_column_from_users'); $this->assertSame('users', $table); $this->assertFalse($create); + + [$table, $create] = TableGuesser::guess('drop_users'); + $this->assertSame('users', $table); + $this->assertFalse($create); } } From a00c792992bcceeb1bbab3db7ff379914d06af25 Mon Sep 17 00:00:00 2001 From: Amir Hossein Date: Wed, 27 Aug 2025 00:49:19 +0330 Subject: [PATCH 2/3] Add drop flag for table guesser --- .../Console/Migrations/MigrateMakeCommand.php | 9 ++--- .../Console/Migrations/TableGuesser.php | 6 ++-- .../Database/Migrations/MigrationCreator.php | 12 +++++-- .../Migrations/stubs/migration.drop.stub | 26 ++++++++++++++ .../Database/DatabaseMigrationCreatorTest.php | 14 ++++++++ tests/Database/TableGuesserTest.php | 36 ++++++++++++------- 6 files changed, 81 insertions(+), 22 deletions(-) create mode 100644 src/Illuminate/Database/Migrations/stubs/migration.drop.stub diff --git a/src/Illuminate/Database/Console/Migrations/MigrateMakeCommand.php b/src/Illuminate/Database/Console/Migrations/MigrateMakeCommand.php index ac5077f58d79..5f5a03c5ee05 100644 --- a/src/Illuminate/Database/Console/Migrations/MigrateMakeCommand.php +++ b/src/Illuminate/Database/Console/Migrations/MigrateMakeCommand.php @@ -89,13 +89,13 @@ public function handle() // "create" in the name. This will allow us to provide a convenient way // of creating migrations that create new tables for the application. if (! $table) { - [$table, $create] = TableGuesser::guess($name); + [$table, $create, $drop] = TableGuesser::guess($name); } // Now we are ready to write the migration out to disk. Once we've written // the migration out, we will dump-autoload for the entire framework to // make sure that the migrations are registered by the class loaders. - $this->writeMigration($name, $table, $create); + $this->writeMigration($name, $table, $create, $drop ?? false); } /** @@ -104,12 +104,13 @@ public function handle() * @param string $name * @param string $table * @param bool $create + * @param bool $drop * @return void */ - protected function writeMigration($name, $table, $create) + protected function writeMigration($name, $table, $create, $drop) { $file = $this->creator->create( - $name, $this->getMigrationPath(), $table, $create + $name, $this->getMigrationPath(), $table, $create, $drop ); if (windows_os()) { diff --git a/src/Illuminate/Database/Console/Migrations/TableGuesser.php b/src/Illuminate/Database/Console/Migrations/TableGuesser.php index 2c90387b06fc..40f792552600 100644 --- a/src/Illuminate/Database/Console/Migrations/TableGuesser.php +++ b/src/Illuminate/Database/Console/Migrations/TableGuesser.php @@ -29,19 +29,19 @@ public static function guess($migration) { foreach (self::CREATE_PATTERNS as $pattern) { if (preg_match($pattern, $migration, $matches)) { - return [$matches[1], $create = true]; + return [$matches[1], $create = true, $drop = false]; } } foreach (self::CHANGE_PATTERNS as $pattern) { if (preg_match($pattern, $migration, $matches)) { - return [$matches[2], $create = false]; + return [$matches[2], $create = false, $drop = false]; } } foreach (self::DROP_PATTERNS as $pattern) { if (preg_match($pattern, $migration, $matches)) { - return [$matches[1], $create = false]; + return [$matches[1], $create = false, $drop = true]; } } } diff --git a/src/Illuminate/Database/Migrations/MigrationCreator.php b/src/Illuminate/Database/Migrations/MigrationCreator.php index ba98eb658148..318646f80393 100755 --- a/src/Illuminate/Database/Migrations/MigrationCreator.php +++ b/src/Illuminate/Database/Migrations/MigrationCreator.php @@ -49,18 +49,19 @@ public function __construct(Filesystem $files, $customStubPath) * @param string $path * @param string|null $table * @param bool $create + * @param bool $drop * @return string * * @throws \Exception */ - public function create($name, $path, $table = null, $create = false) + public function create($name, $path, $table = null, $create = false, $drop = false) { $this->ensureMigrationDoesntAlreadyExist($name, $path); // First we will get the stub file for the migration, which serves as a type // of template for the migration. Once we have those we will populate the // various place-holders, save the file, and run the post create event. - $stub = $this->getStub($table, $create); + $stub = $this->getStub($table, $create, $drop); $path = $this->getPath($name, $path); @@ -107,9 +108,10 @@ protected function ensureMigrationDoesntAlreadyExist($name, $migrationPath = nul * * @param string|null $table * @param bool $create + * @param bool $drop * @return string */ - protected function getStub($table, $create) + protected function getStub($table, $create, $drop) { if (is_null($table)) { $stub = $this->files->exists($customPath = $this->customStubPath.'/migration.stub') @@ -119,6 +121,10 @@ protected function getStub($table, $create) $stub = $this->files->exists($customPath = $this->customStubPath.'/migration.create.stub') ? $customPath : $this->stubPath().'/migration.create.stub'; + } elseif ($drop) { + $stub = $this->files->exists($customPath = $this->customStubPath.'/migration.drop.stub') + ? $customPath + : $this->stubPath().'/migration.drop.stub'; } else { $stub = $this->files->exists($customPath = $this->customStubPath.'/migration.update.stub') ? $customPath diff --git a/src/Illuminate/Database/Migrations/stubs/migration.drop.stub b/src/Illuminate/Database/Migrations/stubs/migration.drop.stub new file mode 100644 index 000000000000..505be4ae82d7 --- /dev/null +++ b/src/Illuminate/Database/Migrations/stubs/migration.drop.stub @@ -0,0 +1,26 @@ +create('create_bar', 'foo', 'baz'); } + public function testTableDropMigrationStoresMigrationFile() + { + $creator = $this->getCreator(); + $creator->expects($this->any())->method('getDatePrefix')->willReturn('foo'); + $creator->getFilesystem()->shouldReceive('exists')->once()->with('stubs/migration.drop.stub')->andReturn(false); + $creator->getFilesystem()->shouldReceive('get')->once()->with($creator->stubPath().'/migration.drop.stub')->andReturn('return new class DummyTable'); + $creator->getFilesystem()->shouldReceive('ensureDirectoryExists')->once()->with('foo'); + $creator->getFilesystem()->shouldReceive('put')->once()->with('foo/foo_create_bar.php', 'return new class baz'); + $creator->getFilesystem()->shouldReceive('glob')->once()->with('foo/*.php')->andReturn(['foo/foo_create_bar.php']); + $creator->getFilesystem()->shouldReceive('requireOnce')->once()->with('foo/foo_create_bar.php'); + + $creator->create('create_bar', 'foo', 'baz', drop: true); + } + public function testTableCreationMigrationStoresMigrationFile() { $creator = $this->getCreator(); diff --git a/tests/Database/TableGuesserTest.php b/tests/Database/TableGuesserTest.php index d0a04c07d16f..f583a86875e5 100644 --- a/tests/Database/TableGuesserTest.php +++ b/tests/Database/TableGuesserTest.php @@ -9,55 +9,67 @@ class TableGuesserTest extends TestCase { public function testMigrationIsProperlyParsed() { - [$table, $create] = TableGuesser::guess('create_users_table'); + [$table, $create, $drop] = TableGuesser::guess('create_users_table'); $this->assertSame('users', $table); $this->assertTrue($create); + $this->assertFalse($drop); - [$table, $create] = TableGuesser::guess('add_status_column_to_users_table'); + [$table, $create, $drop] = TableGuesser::guess('add_status_column_to_users_table'); $this->assertSame('users', $table); $this->assertFalse($create); + $this->assertFalse($drop); - [$table, $create] = TableGuesser::guess('add_is_sent_to_crm_column_to_users_table'); + [$table, $create, $drop] = TableGuesser::guess('add_is_sent_to_crm_column_to_users_table'); $this->assertSame('users', $table); $this->assertFalse($create); + $this->assertFalse($drop); - [$table, $create] = TableGuesser::guess('change_status_column_in_users_table'); + [$table, $create, $drop] = TableGuesser::guess('change_status_column_in_users_table'); $this->assertSame('users', $table); $this->assertFalse($create); + $this->assertFalse($drop); - [$table, $create] = TableGuesser::guess('drop_status_column_from_users_table'); + [$table, $create, $drop] = TableGuesser::guess('drop_status_column_from_users_table'); $this->assertSame('users', $table); $this->assertFalse($create); + $this->assertFalse($drop); - [$table, $create] = TableGuesser::guess('drop_users_table'); + [$table, $create, $drop] = TableGuesser::guess('drop_users_table'); $this->assertSame('users', $table); $this->assertFalse($create); + $this->assertTrue($drop); } public function testMigrationIsProperlyParsedWithoutTableSuffix() { - [$table, $create] = TableGuesser::guess('create_users'); + [$table, $create, $drop] = TableGuesser::guess('create_users'); $this->assertSame('users', $table); $this->assertTrue($create); + $this->assertFalse($drop); - [$table, $create] = TableGuesser::guess('add_status_column_to_users'); + [$table, $create, $drop] = TableGuesser::guess('add_status_column_to_users'); $this->assertSame('users', $table); $this->assertFalse($create); + $this->assertFalse($drop); - [$table, $create] = TableGuesser::guess('add_is_sent_to_crm_column_column_to_users'); + [$table, $create, $drop] = TableGuesser::guess('add_is_sent_to_crm_column_column_to_users'); $this->assertSame('users', $table); $this->assertFalse($create); + $this->assertFalse($drop); - [$table, $create] = TableGuesser::guess('change_status_column_in_users'); + [$table, $create, $drop] = TableGuesser::guess('change_status_column_in_users'); $this->assertSame('users', $table); $this->assertFalse($create); + $this->assertFalse($drop); - [$table, $create] = TableGuesser::guess('drop_status_column_from_users'); + [$table, $create, $drop] = TableGuesser::guess('drop_status_column_from_users'); $this->assertSame('users', $table); $this->assertFalse($create); + $this->assertFalse($drop); - [$table, $create] = TableGuesser::guess('drop_users'); + [$table, $create, $drop] = TableGuesser::guess('drop_users'); $this->assertSame('users', $table); $this->assertFalse($create); + $this->assertTrue($drop); } } From 26eaad8c34c96f590c1632b8475aea7eed04b146 Mon Sep 17 00:00:00 2001 From: Amir Hossein Date: Wed, 27 Aug 2025 01:20:09 +0330 Subject: [PATCH 3/3] fix tests --- tests/Database/DatabaseMigrationMakeCommandTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/Database/DatabaseMigrationMakeCommandTest.php b/tests/Database/DatabaseMigrationMakeCommandTest.php index 79eb535074a5..171f353f9432 100755 --- a/tests/Database/DatabaseMigrationMakeCommandTest.php +++ b/tests/Database/DatabaseMigrationMakeCommandTest.php @@ -28,7 +28,7 @@ public function testBasicCreateDumpsAutoload() $app->useDatabasePath(__DIR__); $command->setLaravel($app); $creator->shouldReceive('create')->once() - ->with('create_foo', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'foo', true) + ->with('create_foo', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'foo', true, false) ->andReturn(__DIR__.'/migrations/2021_04_23_110457_create_foo.php'); $this->runCommand($command, ['name' => 'create_foo']); @@ -44,7 +44,7 @@ public function testBasicCreateGivesCreatorProperArguments() $app->useDatabasePath(__DIR__); $command->setLaravel($app); $creator->shouldReceive('create')->once() - ->with('create_foo', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'foo', true) + ->with('create_foo', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'foo', true, false) ->andReturn(__DIR__.'/migrations/2021_04_23_110457_create_foo.php'); $this->runCommand($command, ['name' => 'create_foo']); @@ -60,7 +60,7 @@ public function testBasicCreateGivesCreatorProperArgumentsWhenNameIsStudlyCase() $app->useDatabasePath(__DIR__); $command->setLaravel($app); $creator->shouldReceive('create')->once() - ->with('create_foo', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'foo', true) + ->with('create_foo', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'foo', true, false) ->andReturn(__DIR__.'/migrations/2021_04_23_110457_create_foo.php'); $this->runCommand($command, ['name' => 'CreateFoo']); @@ -76,7 +76,7 @@ public function testBasicCreateGivesCreatorProperArgumentsWhenTableIsSet() $app->useDatabasePath(__DIR__); $command->setLaravel($app); $creator->shouldReceive('create')->once() - ->with('create_foo', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'users', true) + ->with('create_foo', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'users', true, false) ->andReturn(__DIR__.'/migrations/2021_04_23_110457_create_foo.php'); $this->runCommand($command, ['name' => 'create_foo', '--create' => 'users']); @@ -92,7 +92,7 @@ public function testBasicCreateGivesCreatorProperArgumentsWhenCreateTablePattern $app->useDatabasePath(__DIR__); $command->setLaravel($app); $creator->shouldReceive('create')->once() - ->with('create_users_table', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'users', true) + ->with('create_users_table', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'users', true, false) ->andReturn(__DIR__.'/migrations/2021_04_23_110457_create_users_table.php'); $this->runCommand($command, ['name' => 'create_users_table']); @@ -108,7 +108,7 @@ public function testCanSpecifyPathToCreateMigrationsIn() $command->setLaravel($app); $app->setBasePath('/home/laravel'); $creator->shouldReceive('create')->once() - ->with('create_foo', '/home/laravel/vendor/laravel-package/migrations', 'users', true) + ->with('create_foo', '/home/laravel/vendor/laravel-package/migrations', 'users', true, false) ->andReturn('/home/laravel/vendor/laravel-package/migrations/2021_04_23_110457_create_foo.php'); $this->runCommand($command, ['name' => 'create_foo', '--path' => 'vendor/laravel-package/migrations', '--create' => 'users']); }