Failed Conditions
Pull Request — master (#979)
by Asmir
02:03
created

ExecuteCommand   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 130
Duplicated Lines 0 %

Test Coverage

Coverage 97.1%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 93
dl 0
loc 130
ccs 67
cts 69
cp 0.971
rs 10
c 1
b 0
f 0
wmc 9

2 Methods

Rating   Name   Duplication   Size   Complexity  
B configure() 0 73 1
B execute() 0 50 8
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
use function sprintf;
19
20
/**
21
 * The ExecuteCommand class is responsible for executing migration versions up or down manually.
22
 */
23
final class ExecuteCommand extends DoctrineCommand
24
{
25
    /** @var string */
26
    protected static $defaultName = 'migrations:execute';
27
28 9
    protected function configure() : void
29
    {
30
        $this
31 9
            ->setAliases(['execute'])
32 9
            ->setDescription(
33 9
                'Execute one or more migration versions up or down manually.'
34
            )
35 9
            ->addArgument(
36 9
                'versions',
37 9
                InputArgument::REQUIRED|InputArgument::IS_ARRAY,
38 9
                'The versions to execute.',
39 9
                null
40
            )
41 9
            ->addOption(
42 9
                'write-sql',
43 9
                null,
44 9
                InputOption::VALUE_OPTIONAL,
45 9
                'The path to output the migration SQL file instead of executing it. Defaults to current working directory.',
46 9
                false
47
            )
48 9
            ->addOption(
49 9
                'dry-run',
50 9
                null,
51 9
                InputOption::VALUE_NONE,
52 9
                'Execute the migration as a dry run.'
53
            )
54 9
            ->addOption(
55 9
                'up',
56 9
                null,
57 9
                InputOption::VALUE_NONE,
58 9
                'Execute the migration up.'
59
            )
60 9
            ->addOption(
61 9
                'down',
62 9
                null,
63 9
                InputOption::VALUE_NONE,
64 9
                'Execute the migration down.'
65
            )
66 9
            ->addOption(
67 9
                'query-time',
68 9
                null,
69 9
                InputOption::VALUE_NONE,
70 9
                'Time all the queries individually.'
71
            )
72 9
            ->setHelp(<<<EOT
73 9
The <info>%command.name%</info> command executes migration versions up or down manually:
74
75
    <info>%command.full_name% FQCN</info>
76
77
If no <comment>--up</comment> or <comment>--down</comment> option is specified it defaults to up:
78
79
    <info>%command.full_name% FQCN --down</info>
80
81
You can also execute the migration as a <comment>--dry-run</comment>:
82
83
    <info>%command.full_name% FQCN --dry-run</info>
84
85
You can output the would be executed SQL statements to a file with <comment>--write-sql</comment>:
86
87
    <info>%command.full_name% FQCN --write-sql</info>
88
89
Or you can also execute the migration without a warning message which you need to interact with:
90
91
    <info>%command.full_name% FQCN --no-interaction</info>
92
93
All the previous commands accept multiple migration versions, allowing you run execute more than
94
one migration at once:
95
    <info>%command.full_name% FQCN-1 FQCN-2 ...FQCN-n </info>
96
97
EOT
98
        );
99
100 9
        parent::configure();
101 9
    }
102
103 9
    protected function execute(InputInterface $input, OutputInterface $output) : int
104
    {
105 9
        $migratorConfigurationFactory = $this->getDependencyFactory()->getConsoleInputMigratorConfigurationFactory();
106 9
        $migratorConfiguration        = $migratorConfigurationFactory->getMigratorConfiguration($input);
107
108 9
        $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?';
109 9
        if (! $migratorConfiguration->isDryRun() && ! $this->canExecute($question, $input)) {
110 1
            $this->io->error('Migration cancelled!');
111
112 1
            return 1;
113
        }
114
115 8
        $this->getDependencyFactory()->getMetadataStorage()->ensureInitialized();
116
117 8
        $versions  = $input->getArgument('versions');
118 8
        $direction = $input->getOption('down') !== false
119 8
            ? Direction::DOWN
120 8
            : Direction::UP;
121
122 8
        $path = $input->getOption('write-sql') ?? getcwd();
123 8
        if (is_string($path) && ! is_writable($path)) {
124
            $this->io->error(sprintf('The path "%s" not writeable!', $path));
125
126
            return 1;
127
        }
128
129 8
        $planCalculator = $this->getDependencyFactory()->getMigrationPlanCalculator();
130
        $plan           = $planCalculator->getPlanForVersions(array_map(static function (string $version) : Version {
131 8
            return new Version($version);
132 8
        }, $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

132
        }, /** @scrutinizer ignore-type */ $versions), $direction);
Loading history...
133
134 8
        $this->getDependencyFactory()->getLogger()->notice(
135 8
            'Executing' . ($migratorConfiguration->isDryRun() ? ' (dry-run)' : '') . ' {versions} {direction}',
136
            [
137 8
                'direction' => $plan->getDirection(),
138 8
                '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

138
                'versions' => implode(', ', /** @scrutinizer ignore-type */ $versions),
Loading history...
139
            ]
140
        );
141
142 8
        $migrator = $this->getDependencyFactory()->getMigrator();
143 8
        $sql      = $migrator->migrate($plan, $migratorConfiguration);
144
145 8
        if (is_string($path)) {
146 4
            $writer = $this->getDependencyFactory()->getQueryWriter();
147 4
            $writer->write($path, $direction, $sql);
148
        }
149
150 8
        $this->io->newLine();
151
152 8
        return 0;
153
    }
154
}
155