GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 5e3694...968b0c )
by Robert
9s
created

MigrationsCommand::configure()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 32
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 32
rs 8.8571
ccs 25
cts 25
cp 1
cc 1
eloc 23
nc 1
nop 0
crap 1
1
<?php declare(strict_types=1);
2
3
namespace Gruberro\MongoDbMigrations\Console\Command;
4
5
use Gruberro\MongoDbMigrations;
6
use MongoDB;
7
use Symfony\Component\Console;
8
9
class MigrationsCommand extends Console\Command\Command
10
{
11
    /**
12
     * {@inheritdoc}
13
     */
14 6
    protected function configure()
15
    {
16
        $this
17 6
            ->setName('php-mongodb-migrations:migrate')
18 6
            ->setDescription('Execute all open migrations')
19 6
            ->addOption(
20 6
                'server',
21 6
                's',
22 6
                Console\Input\InputOption::VALUE_REQUIRED,
23 6
                'The connection string (e.g. mongodb://[username:password@]host1[:port1][,host2[:port2:],...]/db)',
24 6
                'mongodb://localhost:27017'
25
            )
26 6
            ->addOption(
27 6
                'contexts',
28 6
                'c',
29 6
                Console\Input\InputOption::VALUE_IS_ARRAY | Console\Input\InputOption::VALUE_REQUIRED,
30 6
                'A list of contexts evaluated with each migration of type ContextualMigrationInterface',
31 6
                []
32
            )
33 6
            ->addArgument(
34 6
                'database',
35 6
                Console\Input\InputArgument::REQUIRED,
36 6
                'The database to connect to'
37
            )
38 6
            ->addArgument(
39 6
                'migration-directories',
40 6
                Console\Input\InputArgument::IS_ARRAY,
41 6
                'List of directories containing migration classes',
42 6
                []
43
            )
44
        ;
45 6
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50 7
    protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
51
    {
52 7
        $client = new MongoDB\Client($input->getOption('server'));
53 7
        $db = $client->selectDatabase($input->getArgument('database'));
54 7
        $output->writeln("<info>✓ Successfully established database connection</info>", $output::VERBOSITY_VERBOSE);
55
56 7
        $directories = $input->getArgument('migration-directories');
57 7
        foreach ($directories as $directory) {
58 7
            if (! is_dir($directory)) {
59 1
                throw new Console\Exception\InvalidArgumentException("'{$directory}' is no valid directory");
60
            }
61
62 7
            $output->writeln("<comment>Iterating '{$directory}' for potential migrations classes</comment>", $output::VERBOSITY_DEBUG);
63 7
            $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($directory), \RecursiveIteratorIterator::LEAVES_ONLY);
64
65
            /** @var \SplFileInfo $file */
66 7
            foreach ($iterator as $file) {
67 7
                if ($file->getBasename('.php') === $file->getBasename()) {
68 7
                    continue;
69
                }
70
71 7
                require_once $file->getRealPath();
72
73 7
                $output->writeln("<comment>Loaded potential migration '{$file->getRealPath()}'</comment>", $output::VERBOSITY_DEBUG);
74
            }
75
        }
76
77
        /** @var MongoDbMigrations\MigrationInterface[] $migrations */
78 6
        $migrations = [];
79 6
        foreach (get_declared_classes() as $className) {
80 6
            $reflectionClass = new \ReflectionClass($className);
81
82 6
            if ($reflectionClass->implementsInterface(MongoDbMigrations\MigrationInterface::class)) {
83
                /** @var MongoDbMigrations\MigrationInterface $newInstance */
84 6
                $newInstance = $reflectionClass->newInstance();
85 6
                $id = md5($newInstance->getId());
86
87 6
                if (isset($migrations[$id])) {
88 1
                    $existingMigrationClass = get_class($migrations[$id]);
89 1
                    throw new Console\Exception\RuntimeException("Found a non unique migration id '{$newInstance->getId()}' in '{$reflectionClass->getName()}', already defined by migration class '{$existingMigrationClass}'");
90
                }
91
92 6
                $migrations[$id] = $newInstance;
93
94 6
                $output->writeln("<comment>Found valid migration class '{$reflectionClass->getName()}'</comment>", $output::VERBOSITY_DEBUG);
95
            }
96
        }
97
98 5
        $migrationClassesCount = count($migrations);
99 5
        $output->writeln("<info>✓ Found {$migrationClassesCount} valid migration classes</info>", $output::VERBOSITY_VERBOSE);
100
101 5
        uasort($migrations, function (MongoDbMigrations\MigrationInterface $a, MongoDbMigrations\MigrationInterface $b) {
102 5
            if ($a->getCreateDate() === $b->getCreateDate()) {
103
                return 0;
104
            }
105
106 5
            return $a->getCreateDate() < $b->getCreateDate() ? -1 : 1;
107 5
        });
108
109 5
        $output->writeln("<info>✓ Reordered all migration classes according to their create date</info>", $output::VERBOSITY_VERBOSE);
110
111 5
        $databaseMigrationsLockCollection = $db->selectCollection('DATABASE_MIGRATIONS_LOCK');
112
113 5
        $currentLock = $databaseMigrationsLockCollection->findOneAndReplace(['locked' => ['$exists' => true]], ['locked' => true, 'last_locked_date' => new MongoDB\BSON\UTCDatetime((new \DateTime())->getTimestamp() * 1000)], ['upsert' => true]);
114 5
        if ($currentLock !== null && $currentLock->locked === true) {
115 1
            throw new Console\Exception\RuntimeException('Concurrent migrations are not allowed');
116
        }
117
118
        try {
119 4
            $output->writeln("<info>✓ Successfully acquired migration lock</info>", $output::VERBOSITY_VERBOSE);
120
121 4
            $databaseMigrationsCollection = $db->selectCollection('DATABASE_MIGRATIONS');
122
123 4
            if (count($databaseMigrationsCollection->listIndexes()) <= 1) {
124 4
                $databaseMigrationsCollection->createIndex(['migration_id' => 1],
125 4
                    ['unique' => true, 'background' => false]);
126
            }
127
128 4
            $progress = new Console\Helper\ProgressBar($output, count($migrations));
129
130 4
            switch ($output->getVerbosity()) {
131 4
                case $output::VERBOSITY_VERBOSE:
132
                    $format = 'verbose';
133
                    break;
134 4
                case $output::VERBOSITY_VERY_VERBOSE:
135
                    $format = 'very_verbose';
136
                    break;
137 4
                case $output::VERBOSITY_DEBUG:
138
                    $format = 'debug';
139
                    break;
140
                default:
141 4
                    $format = 'normal';
142
            }
143
144 4
            $progress->setFormat($format);
145 4
            $progress->start();
146 4
            $executedMigrations = 0;
147
148 4
            foreach ($migrations as $id => $migration) {
149 4
                $progress->advance();
150
151 4
                if ($migration instanceof MongoDbMigrations\ContextualMigrationInterface && $input->getOption('contexts') !== []) {
152 3
                    if (array_intersect($migration->getContexts(), $input->getOption('contexts')) === []) {
153 1
                        continue;
154
                    }
155
                }
156
157 4
                if (!$migration instanceof MongoDbMigrations\RunAlwaysMigrationInterface) {
158 4
                    if ($databaseMigrationsCollection->count(['migration_id' => $id]) > 0) {
159 1
                        continue;
160
                    }
161
                }
162
163 4
                $migration->execute($db);
164 4
                $executedMigrations++;
165
166
                $migrationInfo = [
167 4
                    'migration_id' => $id,
168 4
                    'migration_class' => get_class($migration),
169 4
                    'last_execution_date' => new MongoDB\BSON\UTCDatetime((new \DateTime())->getTimestamp() * 1000),
170 4
                    'run_always' => $migration instanceof MongoDbMigrations\RunAlwaysMigrationInterface,
171
                ];
172
173 4
                if ($migration instanceof MongoDbMigrations\ContextualMigrationInterface) {
174 2
                    $migrationInfo['contexts'] = $migration->getContexts();
175
                }
176
177 4
                $databaseMigrationsCollection->updateOne(
178 4
                    ['migration_id' => $id],
179 4
                    ['$set' => $migrationInfo],
180 4
                    ['upsert' => true]
181
                );
182
            }
183
184 3
            $progress->finish();
185 3
            $output->writeln('');
186
187 3
            $output->writeln("<info>✓ Successfully executed {$executedMigrations} migrations</info>");
188 1
        } catch (\Exception $e) {
189 1
            throw new Console\Exception\RuntimeException('Error while executing migrations', $e->getCode(), $e);
190 3
        } finally {
191 4
            $databaseMigrationsLockCollection->updateOne(['locked' => true], ['$set' => ['locked' => false]]);
192 4
            $output->writeln("<info>✓ Successfully released migration lock</info>", $output::VERBOSITY_VERBOSE);
193
        }
194 3
    }
195
}
196