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 ( b445d1...3a4be1 )
by Robert
02:18
created

MigrationsCommand   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 187
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 8

Test Coverage

Coverage 94.53%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 25
c 1
b 0
f 0
lcom 0
cbo 8
dl 0
loc 187
ccs 121
cts 128
cp 0.9453
rs 10

2 Methods

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