Failed Conditions
Pull Request — master (#968)
by Edi
02:04
created

ExecuteCommand::execute()   B

Complexity

Conditions 9
Paths 12

Size

Total Lines 55
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 9.1442

Importance

Changes 0
Metric Value
cc 9
eloc 33
c 0
b 0
f 0
nc 12
nop 2
dl 0
loc 55
ccs 29
cts 33
cp 0.8788
crap 9.1442
rs 8.0555

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Migrations\Tools\Console\Command;
6
7
use Doctrine\Migrations\Version\Direction;
8
use Doctrine\Migrations\Version\Version;
9
use Symfony\Component\Console\Input\InputArgument;
10
use Symfony\Component\Console\Input\InputInterface;
11
use Symfony\Component\Console\Input\InputOption;
12
use Symfony\Component\Console\Output\OutputInterface;
13
use function array_map;
14
use function getcwd;
15
use function implode;
16
use function is_string;
17
use function is_writable;
18
19
/**
20
 * The ExecuteCommand class is responsible for executing migration versions up or down manually.
21
 */
22
final class ExecuteCommand extends DoctrineCommand
23
{
24
    /** @var string */
25
    protected static $defaultName = 'migrations:execute';
26
27 4
    protected function configure() : void
28
    {
29
        $this
30 4
            ->setAliases(['execute'])
31 4
            ->setDescription(
32 4
                'Execute one or more migration versions up or down manually.'
33
            )
34 4
            ->addArgument(
35 4
                'versions',
36 4
                InputArgument::REQUIRED|InputArgument::IS_ARRAY,
37 4
                'The versions to execute.',
38 4
                null
39
            )
40 4
            ->addOption(
41 4
                'write-sql',
42 4
                null,
43 4
                InputOption::VALUE_OPTIONAL,
44 4
                'The path to output the migration SQL file instead of executing it. Defaults to current working directory.',
45 4
                false
46
            )
47 4
            ->addOption(
48 4
                'dry-run',
49 4
                null,
50 4
                InputOption::VALUE_NONE,
51 4
                'Execute the migration as a dry run.'
52
            )
53 4
            ->addOption(
54 4
                'up',
55 4
                null,
56 4
                InputOption::VALUE_NONE,
57 4
                'Execute the migration up.'
58
            )
59 4
            ->addOption(
60 4
                'down',
61 4
                null,
62 4
                InputOption::VALUE_NONE,
63 4
                'Execute the migration down.'
64
            )
65 4
            ->addOption(
66 4
                'query-time',
67 4
                null,
68 4
                InputOption::VALUE_NONE,
69 4
                'Time all the queries individually.'
70
            )
71 4
            ->setHelp(<<<EOT
72 4
The <info>%command.name%</info> command executes migration versions up or down manually:
73
74
    <info>%command.full_name% FQCN</info>
75
76
If no <comment>--up</comment> or <comment>--down</comment> option is specified it defaults to up:
77
78
    <info>%command.full_name% FQCN --down</info>
79
80
You can also execute the migration as a <comment>--dry-run</comment>:
81
82
    <info>%command.full_name% FQCN --dry-run</info>
83
84
You can output the would be executed SQL statements to a file with <comment>--write-sql</comment>:
85
86
    <info>%command.full_name% FQCN --write-sql</info>
87
88
Or you can also execute the migration without a warning message which you need to interact with:
89
90
    <info>%command.full_name% FQCN --no-interaction</info>
91
92
All the previous commands accept multiple migration versions, allowing you run execute more than
93
one migration at once:
94
    <info>%command.full_name% FQCN-1 FQCN-2 ...FQCN-n </info>
95
96
EOT
97
        );
98
99 4
        parent::configure();
100 4
    }
101
102 4
    protected function execute(InputInterface $input, OutputInterface $output) : int
103
    {
104 4
        $versions  = $input->getArgument('versions');
105 4
        $path      = $input->getOption('write-sql');
106 4
        $direction = $input->getOption('down') !== false
107 4
            ? Direction::DOWN
108 4
            : Direction::UP;
109
110 4
        $migrator       = $this->getDependencyFactory()->getMigrator();
111 4
        $planCalculator = $this->getDependencyFactory()->getMigrationPlanCalculator();
112
        $plan           = $planCalculator->getPlanForVersions(array_map(static function (string $version) : Version {
113 4
            return new Version($version);
114 4
        }, $versions), $direction);
0 ignored issues
show
Bug introduced by
It seems like $versions can also be of type null and string; however, parameter $arr1 of array_map() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

114
        }, /** @scrutinizer ignore-type */ $versions), $direction);
Loading history...
115
116 4
        $migratorConfigurationFactory = $this->getDependencyFactory()->getConsoleInputMigratorConfigurationFactory();
117 4
        $migratorConfiguration        = $migratorConfigurationFactory->getMigratorConfiguration($input);
118
119 4
        if ($path !== false) {
120 2
            $migratorConfiguration->setDryRun(true);
121 2
            $sql = $migrator->migrate($plan, $migratorConfiguration);
122
123 2
            $path = is_string($path) ? $path : getcwd();
124
125 2
            if (! is_string($path) || ! is_writable($path)) {
0 ignored issues
show
introduced by
The condition is_string($path) is always true.
Loading history...
126
                $this->io->error('Path not writeable!');
127
128
                return 1;
129
            }
130
131 2
            $writer = $this->getDependencyFactory()->getQueryWriter();
132 2
            $writer->write($path, $direction, $sql);
133
134 2
            return 0;
135
        }
136
137 2
        $question = 'WARNING! You are about to execute a database migration that could result in schema changes and data lost. Are you sure you wish to continue?';
138
139 2
        if (! $migratorConfiguration->isDryRun() && ! $this->canExecute($question, $input)) {
140
            $this->io->error('Migration cancelled!');
141
142
            return 1;
143
        }
144
145 2
        $this->getDependencyFactory()->getMetadataStorage()->ensureInitialized();
146
147 2
        $this->getDependencyFactory()->getLogger()->notice(
148 2
            'Executing' . ($migratorConfiguration->isDryRun() ? ' (dry-run)' : '') . ' {versions} {direction}',
149
            [
150 2
                'direction' => $plan->getDirection(),
151 2
                'versions' => implode(', ', $versions),
0 ignored issues
show
Bug introduced by
It seems like $versions can also be of type null and string; however, parameter $pieces of implode() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

151
                'versions' => implode(', ', /** @scrutinizer ignore-type */ $versions),
Loading history...
152
            ]
153
        );
154 2
        $migrator->migrate($plan, $migratorConfiguration);
155
156 2
        return 0;
157
    }
158
}
159