Completed
Push — master ( 6e739b...0f594c )
by Asmir
22s queued 12s
created

ExecuteCommand::execute()   B

Complexity

Conditions 9
Paths 11

Size

Total Lines 53
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 9.0197

Importance

Changes 0
Metric Value
cc 9
eloc 32
c 0
b 0
f 0
nc 11
nop 2
dl 0
loc 53
ccs 30
cts 32
cp 0.9375
crap 9.0197
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 5
    protected function configure() : void
28
    {
29
        $this
30 5
            ->setAliases(['execute'])
31 5
            ->setDescription(
32 5
                'Execute one or more migration versions up or down manually.'
33
            )
34 5
            ->addArgument(
35 5
                'versions',
36 5
                InputArgument::REQUIRED|InputArgument::IS_ARRAY,
37 5
                'The versions to execute.',
38 5
                null
39
            )
40 5
            ->addOption(
41 5
                'write-sql',
42 5
                null,
43 5
                InputOption::VALUE_OPTIONAL,
44 5
                'The path to output the migration SQL file instead of executing it. Defaults to current working directory.',
45 5
                false
46
            )
47 5
            ->addOption(
48 5
                'dry-run',
49 5
                null,
50 5
                InputOption::VALUE_NONE,
51 5
                'Execute the migration as a dry run.'
52
            )
53 5
            ->addOption(
54 5
                'up',
55 5
                null,
56 5
                InputOption::VALUE_NONE,
57 5
                'Execute the migration up.'
58
            )
59 5
            ->addOption(
60 5
                'down',
61 5
                null,
62 5
                InputOption::VALUE_NONE,
63 5
                'Execute the migration down.'
64
            )
65 5
            ->addOption(
66 5
                'query-time',
67 5
                null,
68 5
                InputOption::VALUE_NONE,
69 5
                'Time all the queries individually.'
70
            )
71 5
            ->setHelp(<<<EOT
72 5
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 5
        parent::configure();
100 5
    }
101
102 5
    protected function execute(InputInterface $input, OutputInterface $output) : int
103
    {
104 5
        $migratorConfigurationFactory = $this->getDependencyFactory()->getConsoleInputMigratorConfigurationFactory();
105 5
        $migratorConfiguration        = $migratorConfigurationFactory->getMigratorConfiguration($input);
106
107 5
        $question = 'WARNING! You are about to execute a database migration that could result in schema changes and data loss. Are you sure you wish to continue?';
108 5
        if (! $migratorConfiguration->isDryRun() && ! $this->canExecute($question, $input)) {
109 1
            $this->io->error('Migration cancelled!');
110
111 1
            return 1;
112
        }
113
114 4
        $this->getDependencyFactory()->getMetadataStorage()->ensureInitialized();
115
116 4
        $versions  = $input->getArgument('versions');
117 4
        $path      = $input->getOption('write-sql');
118 4
        $direction = $input->getOption('down') !== false
119 4
            ? Direction::DOWN
120 4
            : Direction::UP;
121
122 4
        $migrator       = $this->getDependencyFactory()->getMigrator();
123 4
        $planCalculator = $this->getDependencyFactory()->getMigrationPlanCalculator();
124
        $plan           = $planCalculator->getPlanForVersions(array_map(static function (string $version) : Version {
125 4
            return new Version($version);
126 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

126
        }, /** @scrutinizer ignore-type */ $versions), $direction);
Loading history...
127
128 4
        if ($migratorConfiguration->isDryRun()) {
129 2
            $sql = $migrator->migrate($plan, $migratorConfiguration);
130
131 2
            $path = is_string($path) ? $path : getcwd();
132
133 2
            if (! is_string($path) || ! is_writable($path)) {
0 ignored issues
show
introduced by
The condition is_string($path) is always true.
Loading history...
134
                $this->io->error('Path not writeable!');
135
136
                return 1;
137
            }
138
139 2
            $writer = $this->getDependencyFactory()->getQueryWriter();
140 2
            $writer->write($path, $direction, $sql);
141
142 2
            return 0;
143
        }
144
145 2
        $this->getDependencyFactory()->getLogger()->notice(
146 2
            'Executing' . ($migratorConfiguration->isDryRun() ? ' (dry-run)' : '') . ' {versions} {direction}',
147
            [
148 2
                'direction' => $plan->getDirection(),
149 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

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