Failed Conditions
Push — master ( 9f9094...c8307c )
by
unknown
30:17 queued 23:03
created

src/Console/RollbackNewMigrations.php (1 issue)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Umbrellio\RollbackMissingMigrations\Console;
6
7
use Illuminate\Console\Command;
8
use Illuminate\Database\Migrations\Migration;
9
use Illuminate\Support\Collection;
10
use Illuminate\Support\Facades\App;
11
use Illuminate\Support\Facades\DB;
12
use Illuminate\Support\Facades\File;
13
use Illuminate\Support\Str;
14
use SplFileInfo;
15
16
class RollbackNewMigrations extends Command
17
{
18
    private const COMMAND_PATTERN = 'git ls-tree --name-only origin/master {git_migrations_path}';
19
20
    protected $signature = 'rollback_new_migrations:rollback {--git_migrations_path=}';
21
    protected $description = 'Rollback new migrations (default way for k8s staging)';
22
23
    public function handle(): void
24
    {
25
        if (App::environment('production')) {
26
            $this->error('It`s restricted to rollback new migrations on production.');
27
            return;
28
        }
29
30
        $gitMigrationsPath = $this->option('git_migrations_path') ?? 'database/migrations/';
31
        $gitCommand = str_replace('{git_migrations_path}', $gitMigrationsPath, self::COMMAND_PATTERN);
32
33
        $migrationsFromMaster = collect(explode(PHP_EOL, shell_exec($gitCommand)))
34
            ->filter()
35
            ->map(fn (string $path) => new SplFileInfo(base_path($path)));
36
        $migrationsFromCurrent = collect(File::files(base_path('database/migrations')));
37
38
        /** @var Collection|SplFileInfo[] $migrationsToRollback */
39
        $migrationsToRollback = $migrationsFromCurrent->keyBy->getFileName()
40
            ->diffKeys($migrationsFromMaster->keyBy->getFileName())
41
            ->sort(fn (SplFileInfo $file1, SplFileInfo $file2) => strcmp($file1->getFilename(), $file2->getFilename()))
42
            ->reverse();
43
44
        if ($migrationsToRollback->isEmpty()) {
45
            $this->info('There are no migrations to rollback.');
46
            return;
47
        }
48
49
        DB::transaction(function () use ($migrationsToRollback) {
50
            foreach ($migrationsToRollback as $migration) {
51
                $this->info('Rolling back: ' . $migration->getFilename());
52
                $this->downMigrationFile($migration);
53
            }
54
        });
55
    }
56
57
    private function downMigrationFile(SplFileInfo $f): void
58
    {
59
        $migration = require_once $f;
60
        $filename = explode('.php', $f->getRelativePathname())[0];
0 ignored issues
show
The method getRelativePathname() does not exist on SplFileInfo. It seems like you code against a sub-type of SplFileInfo such as Nette\Utils\FileInfo or Psy\Readline\Hoa\IteratorSplFileInfo or ECSPrefix20211002\Symfon...nent\Finder\SplFileInfo or Symfony\Component\Finder\SplFileInfo or Illuminate\Http\UploadedFile. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

60
        $filename = explode('.php', $f->/** @scrutinizer ignore-call */ getRelativePathname())[0];
Loading history...
61
        if (!$migration instanceof Migration) {
62
            $class = Str::studly(implode('_', array_slice(explode('_', $filename), 4)));
63
            $migration = new $class();
64
        }
65
        if (method_exists($migration, 'down')) {
66
            $migration->down();
67
            DB::table(config('database.migrations', 'migrations'))->where('migration', $filename)->delete();
68
        }
69
    }
70
}
71