From b11ae236b96a2aca8783bfc8c7d0fff389015e82 Mon Sep 17 00:00:00 2001 From: Andrey Helldar Date: Mon, 31 Mar 2025 21:54:26 +0300 Subject: [PATCH 1/2] Added `withOperation` method to migration --- src/Listeners/Listener.php | 40 +++++++++++++++++++ src/Listeners/MigrationEndedListener.php | 17 ++++++++ src/ServiceProvider.php | 10 +++++ tests/Commands/OperationsTest.php | 32 +++++++++++++++ tests/Concerns/Files.php | 8 ++++ .../2025_03_31_213407_custom.php | 22 ++++++++++ .../2025_03_31_234251_invoke.php | 22 ++++++++++ .../2025_03_31_234312_up_down.php | 29 ++++++++++++++ .../2025_03_31_213847_call_invokable.php | 19 +++++++++ .../2025_03_31_213921_call_up_down.php | 19 +++++++++ 10 files changed, 218 insertions(+) create mode 100644 src/Listeners/Listener.php create mode 100644 src/Listeners/MigrationEndedListener.php create mode 100644 tests/fixtures/app/via_migrations/2025_03_31_213407_custom.php create mode 100644 tests/fixtures/app/via_migrations/2025_03_31_234251_invoke.php create mode 100644 tests/fixtures/app/via_migrations/2025_03_31_234312_up_down.php create mode 100644 tests/fixtures/migrations_with_operations/2025_03_31_213847_call_invokable.php create mode 100644 tests/fixtures/migrations_with_operations/2025_03_31_213921_call_up_down.php diff --git a/src/Listeners/Listener.php b/src/Listeners/Listener.php new file mode 100644 index 00000000..a6a177ff --- /dev/null +++ b/src/Listeners/Listener.php @@ -0,0 +1,40 @@ +withOperation(); + } + + return null; + } + + protected function run(string $method, string $operation): void + { + match ($method) { + 'up' => $this->call(OperationsCommand::class, $operation), + 'down' => $this->call(RollbackCommand::class, $operation, ['--force' => true]), + }; + } + + protected function call(string $command, string $filename, array $parameters = []): void + { + Artisan::call($command, array_merge([ + '--' . Options::Path => $filename, + ], $parameters)); + } +} diff --git a/src/Listeners/MigrationEndedListener.php b/src/Listeners/MigrationEndedListener.php new file mode 100644 index 00000000..44486727 --- /dev/null +++ b/src/Listeners/MigrationEndedListener.php @@ -0,0 +1,17 @@ +withOperation($event->migration)) { + $this->run($event->method, $operation); + } + } +} diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index 78f28448..c26d7bfa 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -5,6 +5,9 @@ namespace DragonCode\LaravelDeployOperations; use DragonCode\LaravelDeployOperations\Concerns\HasAbout; +use DragonCode\LaravelDeployOperations\Listeners\MigrationEndedListener; +use Illuminate\Database\Events\MigrationEnded; +use Illuminate\Support\Facades\Event; use Illuminate\Support\ServiceProvider as BaseServiceProvider; class ServiceProvider extends BaseServiceProvider @@ -21,6 +24,8 @@ public function boot(): void $this->registerCommands(); $this->registerMigrations(); } + + $this->registerEvents(); } public function register(): void @@ -42,6 +47,11 @@ protected function registerCommands(): void ]); } + protected function registerEvents(): void + { + Event::listen(MigrationEnded::class, MigrationEndedListener::class); + } + protected function registerMigrations(): void { $this->loadMigrationsFrom(__DIR__ . '/../database/migrations'); diff --git a/tests/Commands/OperationsTest.php b/tests/Commands/OperationsTest.php index 6cdffebc..86e881ea 100644 --- a/tests/Commands/OperationsTest.php +++ b/tests/Commands/OperationsTest.php @@ -7,6 +7,7 @@ use DragonCode\LaravelDeployOperations\Constants\Names; use DragonCode\LaravelDeployOperations\Jobs\OperationJob; use Exception; +use Illuminate\Database\Console\Migrations\MigrateCommand; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Queue; use Illuminate\Support\Str; @@ -746,4 +747,35 @@ public function testSync() $this->assertDatabaseOperationHas($this->table, 'foo_bar'); $this->assertDatabaseOperationDoesntLike($this->table, 'every_time'); } + + public function testViaMigrationMethod() + { + $this->loadMigrationsFrom(__DIR__ . '/../fixtures/migrations_with_operations'); + + $this->copyViaMigrations(); + + $table = 'test'; + + $this->artisan(Names::Install)->assertExitCode(0); + + $this->assertDatabaseCount($table, 0); + $this->assertDatabaseCount($this->table, 0); + $this->assertDatabaseOperationDoesntLike($this->table, 'custom'); + $this->assertDatabaseOperationDoesntLike($this->table, 'invoke'); + $this->assertDatabaseOperationDoesntLike($this->table, 'up_down'); + $this->assertDatabaseOperationDoesntLike($table, 'custom', column: 'value'); + $this->assertDatabaseOperationDoesntLike($table, 'invoke', column: 'value'); + $this->assertDatabaseOperationDoesntLike($table, 'up_down', column: 'value'); + + $this->artisan(MigrateCommand::class)->assertExitCode(0); + + $this->assertDatabaseCount($table, 2); + $this->assertDatabaseCount($this->table, 2); + $this->assertDatabaseOperationDoesntLike($this->table, 'custom'); + $this->assertDatabaseOperationHas($this->table, 'invoke'); + $this->assertDatabaseOperationHas($this->table, 'up_down'); + $this->assertDatabaseOperationDoesntLike($table, 'custom', column: 'value'); + $this->assertDatabaseOperationHas($table, 'invoke', column: 'value'); + $this->assertDatabaseOperationHas($table, 'up_down', column: 'value'); + } } diff --git a/tests/Concerns/Files.php b/tests/Concerns/Files.php index f150d233..892b8db9 100644 --- a/tests/Concerns/Files.php +++ b/tests/Concerns/Files.php @@ -50,6 +50,14 @@ protected function copyDI(): void ); } + protected function copyViaMigrations(): void + { + File::copyDirectory( + __DIR__ . '/../fixtures/app/via_migrations', + $this->targetDirectory() + ); + } + protected function copySuccessFailureMethod(): void { File::copy( diff --git a/tests/fixtures/app/via_migrations/2025_03_31_213407_custom.php b/tests/fixtures/app/via_migrations/2025_03_31_213407_custom.php new file mode 100644 index 00000000..4e566652 --- /dev/null +++ b/tests/fixtures/app/via_migrations/2025_03_31_213407_custom.php @@ -0,0 +1,22 @@ +table()->insert([ + 'value' => $some->get('custom'), + ]); + } + + protected function table(): Builder + { + return DB::table('test'); + } +}; diff --git a/tests/fixtures/app/via_migrations/2025_03_31_234251_invoke.php b/tests/fixtures/app/via_migrations/2025_03_31_234251_invoke.php new file mode 100644 index 00000000..9a95574b --- /dev/null +++ b/tests/fixtures/app/via_migrations/2025_03_31_234251_invoke.php @@ -0,0 +1,22 @@ +table()->insert([ + 'value' => $some->get('invoke'), + ]); + } + + protected function table(): Builder + { + return DB::table('test'); + } +}; diff --git a/tests/fixtures/app/via_migrations/2025_03_31_234312_up_down.php b/tests/fixtures/app/via_migrations/2025_03_31_234312_up_down.php new file mode 100644 index 00000000..c500d993 --- /dev/null +++ b/tests/fixtures/app/via_migrations/2025_03_31_234312_up_down.php @@ -0,0 +1,29 @@ +table()->insert([ + 'value' => $some->get('up_down'), + ]); + } + + public function down(Some $some): void + { + $this->table() + ->where('value', $some->get('up_down')) + ->delete(); + } + + protected function table(): Builder + { + return DB::table('test'); + } +}; diff --git a/tests/fixtures/migrations_with_operations/2025_03_31_213847_call_invokable.php b/tests/fixtures/migrations_with_operations/2025_03_31_213847_call_invokable.php new file mode 100644 index 00000000..21a17c67 --- /dev/null +++ b/tests/fixtures/migrations_with_operations/2025_03_31_213847_call_invokable.php @@ -0,0 +1,19 @@ + Date: Tue, 1 Apr 2025 21:42:32 +0300 Subject: [PATCH 2/2] Fixed a call of operations --- src/Data/Casts/PathCast.php | 13 ++++++++++-- src/Services/MigratorService.php | 6 ++++++ tests/Commands/OperationsTest.php | 20 +++++++++++++++---- .../2025_03_31_213847_call_invokable.php | 5 +---- .../2025_03_31_213921_call_up_down.php | 5 +---- 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/Data/Casts/PathCast.php b/src/Data/Casts/PathCast.php index 2b242c12..061c4002 100644 --- a/src/Data/Casts/PathCast.php +++ b/src/Data/Casts/PathCast.php @@ -5,21 +5,30 @@ namespace DragonCode\LaravelDeployOperations\Data\Casts; use DragonCode\LaravelDeployOperations\Helpers\ConfigHelper; +use Illuminate\Support\Str; use Spatie\LaravelData\Casts\Cast; use Spatie\LaravelData\Support\Creation\CreationContext; use Spatie\LaravelData\Support\DataProperty; use function app; +use function realpath; class PathCast implements Cast { public function cast(DataProperty $property, mixed $value, array $properties, CreationContext $context): string { + $path = $this->config()->basePath((string) $value); + if ($properties['realpath'] ?? false) { - return $value ?: $this->config()->basePath(); + return $value ?: $path; } - return $this->config()->basePath($value); + return $this->filename($path) ?: $path; + } + + protected function filename(string $path): false|string + { + return realpath(Str::finish($path, '.php')); } protected function config(): ConfigHelper diff --git a/src/Services/MigratorService.php b/src/Services/MigratorService.php index 41f0ba46..97ccbbf3 100644 --- a/src/Services/MigratorService.php +++ b/src/Services/MigratorService.php @@ -19,6 +19,8 @@ use Illuminate\Support\Facades\DB; use Throwable; +use function file_exists; +use function is_file; use function method_exists; use function realpath; @@ -148,6 +150,10 @@ protected function disallowBefore(Operation $operation, OptionsData $options): b protected function resolvePath(string $filename, string $path): string { + if (file_exists($path) && is_file($path)) { + return $path; + } + $withExtension = Str::finish($filename, '.php'); if ($this->file->exists($withExtension) && $this->file->isFile($withExtension)) { diff --git a/tests/Commands/OperationsTest.php b/tests/Commands/OperationsTest.php index 86e881ea..dec1e2ab 100644 --- a/tests/Commands/OperationsTest.php +++ b/tests/Commands/OperationsTest.php @@ -7,7 +7,7 @@ use DragonCode\LaravelDeployOperations\Constants\Names; use DragonCode\LaravelDeployOperations\Jobs\OperationJob; use Exception; -use Illuminate\Database\Console\Migrations\MigrateCommand; +use Illuminate\Database\Console\Migrations\RollbackCommand; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Queue; use Illuminate\Support\Str; @@ -750,8 +750,6 @@ public function testSync() public function testViaMigrationMethod() { - $this->loadMigrationsFrom(__DIR__ . '/../fixtures/migrations_with_operations'); - $this->copyViaMigrations(); $table = 'test'; @@ -767,7 +765,7 @@ public function testViaMigrationMethod() $this->assertDatabaseOperationDoesntLike($table, 'invoke', column: 'value'); $this->assertDatabaseOperationDoesntLike($table, 'up_down', column: 'value'); - $this->artisan(MigrateCommand::class)->assertExitCode(0); + $this->loadMigrationsFrom(__DIR__ . '/../fixtures/migrations_with_operations'); $this->assertDatabaseCount($table, 2); $this->assertDatabaseCount($this->table, 2); @@ -777,5 +775,19 @@ public function testViaMigrationMethod() $this->assertDatabaseOperationDoesntLike($table, 'custom', column: 'value'); $this->assertDatabaseOperationHas($table, 'invoke', column: 'value'); $this->assertDatabaseOperationHas($table, 'up_down', column: 'value'); + + $this->artisan(RollbackCommand::class, [ + '--path' => __DIR__ . '/../fixtures/migrations_with_operations', + '--realpath' => true, + ])->assertSuccessful(); + + $this->assertDatabaseCount($table, 1); + $this->assertDatabaseCount($this->table, 0); + $this->assertDatabaseOperationDoesntLike($this->table, 'custom'); + $this->assertDatabaseOperationDoesntLike($this->table, 'invoke'); + $this->assertDatabaseOperationDoesntLike($this->table, 'up_down'); + $this->assertDatabaseOperationDoesntLike($table, 'custom', column: 'value'); + $this->assertDatabaseOperationHas($table, 'invoke', column: 'value'); + $this->assertDatabaseOperationDoesntLike($table, 'up_down', column: 'value'); } } diff --git a/tests/fixtures/migrations_with_operations/2025_03_31_213847_call_invokable.php b/tests/fixtures/migrations_with_operations/2025_03_31_213847_call_invokable.php index 21a17c67..138e8a7b 100644 --- a/tests/fixtures/migrations_with_operations/2025_03_31_213847_call_invokable.php +++ b/tests/fixtures/migrations_with_operations/2025_03_31_213847_call_invokable.php @@ -5,10 +5,7 @@ use Illuminate\Database\Migrations\Migration; return new class extends Migration { - public function up(): void - { - // - } + public function up(): void {} public function down(): void {} diff --git a/tests/fixtures/migrations_with_operations/2025_03_31_213921_call_up_down.php b/tests/fixtures/migrations_with_operations/2025_03_31_213921_call_up_down.php index 5d58b789..7f70fd87 100644 --- a/tests/fixtures/migrations_with_operations/2025_03_31_213921_call_up_down.php +++ b/tests/fixtures/migrations_with_operations/2025_03_31_213921_call_up_down.php @@ -5,10 +5,7 @@ use Illuminate\Database\Migrations\Migration; return new class extends Migration { - public function up(): void - { - // - } + public function up(): void {} public function down(): void {}