Failed Conditions
Pull Request — master (#923)
by
unknown
11:18
created

DiffCommand   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 144
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
eloc 97
dl 0
loc 144
ccs 0
cts 90
cp 0
rs 10
c 0
b 0
f 0
wmc 11

2 Methods

Rating   Name   Duplication   Size   Complexity  
B execute() 0 73 10
A configure() 0 60 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Migrations\Tools\Console\Command;
6
7
use Doctrine\Migrations\Generator\Exception\NoChangesDetected;
8
use Doctrine\Migrations\Tools\Console\Exception\InvalidOptionUsage;
9
use OutOfBoundsException;
10
use Symfony\Component\Console\Input\InputInterface;
11
use Symfony\Component\Console\Input\InputOption;
12
use Symfony\Component\Console\Output\OutputInterface;
13
use function addslashes;
14
use function assert;
15
use function class_exists;
16
use function filter_var;
17
use function is_string;
18
use function key;
19
use function sprintf;
20
use const FILTER_VALIDATE_BOOLEAN;
21
22
/**
23
 * The DiffCommand class is responsible for generating a migration by comparing your current database schema to
24
 * your mapping information.
25
 */
26
class DiffCommand extends DoctrineCommand
27
{
28
    /** @var string */
29
    protected static $defaultName = 'migrations:diff';
30
31
    protected function configure() : void
32
    {
33
        parent::configure();
34
35
        $this
36
            ->setAliases(['diff'])
37
            ->setDescription('Generate a migration by comparing your current database to your mapping information.')
38
            ->setHelp(<<<EOT
39
The <info>%command.name%</info> command generates a migration by comparing your current database to your mapping information:
40
41
    <info>%command.full_name%</info>
42
43
You can optionally specify a <comment>--editor-cmd</comment> option to open the generated file in your favorite editor:
44
45
    <info>%command.full_name% --editor-cmd=mate</info>
46
EOT
47
            )
48
            ->addOption(
49
                'namespace',
50
                null,
51
                InputOption::VALUE_REQUIRED,
52
                'The namespace to use for the migration (must be in the list of configured namespaces)'
53
            )
54
            ->addOption(
55
                'editor-cmd',
56
                null,
57
                InputOption::VALUE_REQUIRED,
58
                'Open file with this command upon creation.'
59
            )
60
            ->addOption(
61
                'filter-expression',
62
                null,
63
                InputOption::VALUE_REQUIRED,
64
                'Tables which are filtered by Regular Expression.'
65
            )
66
            ->addOption(
67
                'formatted',
68
                null,
69
                InputOption::VALUE_NONE,
70
                'Format the generated SQL.'
71
            )
72
            ->addOption(
73
                'line-length',
74
                null,
75
                InputOption::VALUE_REQUIRED,
76
                'Max line length of unformatted lines.',
77
                120
78
            )
79
            ->addOption(
80
                'check-database-platform',
81
                null,
82
                InputOption::VALUE_OPTIONAL,
83
                'Check Database Platform to the generated code.',
84
                false
85
            )
86
            ->addOption(
87
                'allow-empty-diff',
88
                null,
89
                InputOption::VALUE_NONE,
90
                'Do not throw an exception when no changes are detected.'
91
            );
92
    }
93
94
    /**
95
     * @throws InvalidOptionUsage
96
     */
97
    protected function execute(
98
        InputInterface $input,
99
        OutputInterface $output
100
    ) : ?int {
101
        $filterExpression = (string) $input->getOption('filter-expression') ?: null;
102
        $formatted        = filter_var($input->getOption('formatted'), FILTER_VALIDATE_BOOLEAN);
103
        $lineLength       = (int) $input->getOption('line-length');
104
        $allowEmptyDiff   = $input->getOption('allow-empty-diff');
105
        $checkDbPlatform  = filter_var($input->getOption('check-database-platform'), FILTER_VALIDATE_BOOLEAN);
106
        $namespace        = $input->getOption('namespace') ?: null;
107
        if ($formatted) {
108
            if (! class_exists('SqlFormatter')) {
109
                throw InvalidOptionUsage::new(
110
                    'The "--formatted" option can only be used if the sql formatter is installed. Please run "composer require jdorn/sql-formatter".'
111
                );
112
            }
113
        }
114
115
        $configuration = $this->getDependencyFactory()->getConfiguration();
116
117
        $dirs = $configuration->getMigrationDirectories();
118
        if ($namespace === null) {
119
            $namespace = key($dirs);
120
        } elseif (! isset($dirs[$namespace])) {
121
            throw new OutOfBoundsException(sprintf('Path not defined for the namespace %s', $namespace));
122
        }
123
124
        assert(is_string($namespace));
125
126
        $fqcn = $this->getDependencyFactory()->getClassNameGenerator()->generateClassName($namespace);
127
128
        $diffGenerator = $this->getDependencyFactory()->getDiffGenerator();
129
130
        try {
131
            $path = $diffGenerator->generate(
132
                $fqcn,
133
                $filterExpression,
134
                $formatted,
135
                $lineLength,
136
                $checkDbPlatform
137
            );
138
        } catch (NoChangesDetected $exception) {
139
            if ($allowEmptyDiff) {
140
                $output->writeln($exception->getMessage());
141
142
                return 0;
143
            }
144
145
            throw $exception;
146
        }
147
148
        $editorCommand = $input->getOption('editor-cmd');
149
150
        if ($editorCommand !== null) {
151
            assert(is_string($editorCommand));
152
            $this->procOpen($editorCommand, $path);
153
        }
154
155
        $output->writeln([
156
            sprintf('Generated new migration class to "<info>%s</info>"', $path),
157
            '',
158
            sprintf(
159
                'To run just this migration for testing purposes, you can use <info>migrations:execute --up \'%s\'</info>',
160
                addslashes($fqcn)
161
            ),
162
            '',
163
            sprintf(
164
                'To revert the migration you can use <info>migrations:execute --down \'%s\'</info>',
165
                addslashes($fqcn)
166
            ),
167
        ]);
168
169
        return 0;
170
    }
171
}
172