Failed Conditions
Pull Request — master (#632)
by Michael
02:44
created

GenerateCommand   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Test Coverage

Coverage 90.74%

Importance

Changes 0
Metric Value
dl 0
loc 146
ccs 49
cts 54
cp 0.9074
rs 10
c 0
b 0
f 0
wmc 13

5 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 23 1
B generateMigration() 0 36 4
B loadCustomTemplate() 0 27 5
A execute() 0 10 1
A getTemplate() 0 7 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Migrations\Tools\Console\Command;
6
7
use Doctrine\Migrations\Configuration\Configuration;
8
use Doctrine\Migrations\Tools\Console\Helper\MigrationDirectoryHelper;
9
use InvalidArgumentException;
10
use Symfony\Component\Console\Input\InputInterface;
11
use Symfony\Component\Console\Input\InputOption;
12
use Symfony\Component\Console\Output\OutputInterface;
13
use function escapeshellarg;
14
use function explode;
15
use function file_get_contents;
16
use function file_put_contents;
17
use function implode;
18
use function is_file;
19
use function is_readable;
20
use function preg_replace;
21
use function proc_open;
22
use function sprintf;
23
use function str_replace;
24
25
class GenerateCommand extends AbstractCommand
26
{
27
    private const MIGRATION_TEMPLATE = <<<'TEMPLATE'
28
<?php
29
30
declare(strict_types=1);
31
32
namespace <namespace>;
33
34
use Doctrine\Migrations\AbstractMigration;
35
use Doctrine\DBAL\Schema\Schema;
36
37
/**
38
 * Auto-generated Migration: Please modify to your needs!
39
 */
40
final class Version<version> extends AbstractMigration
41
{
42
    public function up(Schema $schema) : void
43
    {
44
        // this up() migration is auto-generated, please modify it to your needs
45
<up>
46
    }
47
48
    public function down(Schema $schema) : void
49
    {
50
        // this down() migration is auto-generated, please modify it to your needs
51
<down>
52
    }
53
}
54
55
TEMPLATE;
56
57
    /** @var null|string */
58
    private $instanceTemplate;
59
60 15
    protected function configure() : void
61
    {
62
        $this
63 15
            ->setName('migrations:generate')
64 15
            ->setDescription('Generate a blank migration class.')
65 15
            ->addOption(
66 15
                'editor-cmd',
67 15
                null,
68 15
                InputOption::VALUE_OPTIONAL,
69 15
                'Open file with this command upon creation.'
70
            )
71 15
            ->setHelp(<<<EOT
72 15
The <info>%command.name%</info> command generates a blank migration class:
73
74
    <info>%command.full_name%</info>
75
76
You can optionally specify a <comment>--editor-cmd</comment> option to open the generated file in your favorite editor:
77
78
    <info>%command.full_name% --editor-cmd=mate</info>
79
EOT
80
        );
81
82 15
        parent::configure();
83 15
    }
84
85 6
    public function execute(InputInterface $input, OutputInterface $output) : void
86
    {
87 6
        $configuration = $this->getMigrationConfiguration($input, $output);
88
89 6
        $this->loadCustomTemplate($configuration, $output);
90
91 5
        $version = $configuration->generateVersionNumber();
92 5
        $path    = $this->generateMigration($configuration, $input, $version);
93
94 5
        $output->writeln(sprintf('Generated new migration class to "<info>%s</info>"', $path));
95 5
    }
96
97 13
    protected function getTemplate() : string
98
    {
99 13
        if ($this->instanceTemplate === null) {
100 9
            $this->instanceTemplate = self::MIGRATION_TEMPLATE;
101
        }
102
103 13
        return $this->instanceTemplate;
104
    }
105
106 13
    protected function generateMigration(
107
        Configuration $configuration,
108
        InputInterface $input,
109
        string $version,
110
        ?string $up = null,
111
        ?string $down = null
112
    ) : string {
113
        $placeHolders = [
114 13
            '<namespace>',
115
            '<version>',
116
            '<up>',
117
            '<down>',
118
        ];
119
        $replacements = [
120 13
            $configuration->getMigrationsNamespace(),
121 13
            $version,
122 13
            $up ? '        ' . implode("\n        ", explode("\n", $up)) : null,
123 13
            $down ? '        ' . implode("\n        ", explode("\n", $down)) : null,
124
        ];
125
126 13
        $code = str_replace($placeHolders, $replacements, $this->getTemplate());
127 13
        $code = preg_replace('/^ +$/m', '', $code);
128
129 13
        $directoryHelper = new MigrationDirectoryHelper($configuration);
130 13
        $dir             = $directoryHelper->getMigrationDirectory();
131 13
        $path            = $dir . '/Version' . $version . '.php';
132
133 13
        file_put_contents($path, $code);
134
135 13
        $editorCmd = $input->getOption('editor-cmd');
136
137 13
        if ($editorCmd) {
138
            proc_open($editorCmd . ' ' . escapeshellarg($path), [], $pipes);
139
        }
140
141 13
        return $path;
142
    }
143
144 14
    protected function loadCustomTemplate(Configuration $configuration, OutputInterface $output) : void
145
    {
146 14
        $customTemplate = $configuration->getCustomTemplate();
147
148 14
        if ($customTemplate === null) {
149 9
            return;
150
        }
151
152 5
        if (! is_file($customTemplate) || ! is_readable($customTemplate)) {
153 1
            throw new InvalidArgumentException(
154 1
                'The specified template "' . $customTemplate . '" cannot be found or is not readable.'
155
            );
156
        }
157
158 4
        $content = file_get_contents($customTemplate);
159
160 4
        if ($content === false) {
161
            throw new InvalidArgumentException(
162
                sprintf(
163
                    'The specified template "%s" could not be read.',
164
                    $customTemplate
165
                )
166
            );
167
        }
168
169 4
        $output->writeln(sprintf('Using custom migration template "<info>%s</info>"', $customTemplate));
170 4
        $this->instanceTemplate = $content;
171 4
    }
172
}
173