-
-
Notifications
You must be signed in to change notification settings - Fork 16
/
UpdateCommand.php
134 lines (107 loc) · 4.11 KB
/
UpdateCommand.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<?php
declare(strict_types=1);
namespace Yiisoft\Yii\Db\Migration\Command;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Style\SymfonyStyle;
use Yiisoft\Yii\Db\Migration\Informer\ConsoleMigrationInformer;
use Yiisoft\Yii\Db\Migration\Migrator;
use Yiisoft\Yii\Db\Migration\Runner\UpdateRunner;
use Yiisoft\Yii\Db\Migration\Service\MigrationService;
use function array_slice;
use function count;
use function strlen;
/**
* Applies new migrations.
*
* For example,
*
* ```
* yii migrate:up # apply all new migrations
* yii migrate:up --limit=3 # apply the first 3 new migrations
* ```
*/
#[AsCommand('migrate:up', 'Applies new migrations.')]
final class UpdateCommand extends Command
{
public function __construct(
private UpdateRunner $updateRunner,
private MigrationService $migrationService,
private Migrator $migrator,
ConsoleMigrationInformer $informer
) {
parent::__construct();
}
protected function configure(): void
{
$this->addOption('limit', 'l', InputOption::VALUE_OPTIONAL, 'Number of migrations to apply.', '0');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$this->migrationService->setIO($io);
$this->updateRunner->setIO($io);
if ($this->migrationService->before(self::getDefaultName() ?? '') === Command::INVALID) {
return Command::INVALID;
}
$limit = (int) $input->getOption('limit');
/** @psalm-var class-string[] $migrations */
$migrations = $this->migrationService->getNewMigrations();
if (empty($migrations)) {
$output->writeln("<fg=green> >>> No new migrations found.</>\n");
$io->success('Your system is up-to-date.');
$this->migrationService->databaseConnection();
return Command::SUCCESS;
}
$total = count($migrations);
if ($limit > 0) {
$migrations = array_slice($migrations, 0, $limit);
}
$n = count($migrations);
if ($n === $total) {
$output->writeln(
"<fg=yellow>Total $n new " . ($n === 1 ? 'migration' : 'migrations') . ' to be ' .
"applied:</>\n"
);
} else {
$output->writeln(
"<fg=yellow>Total $n out of $total new " . ($total === 1 ? 'migration' : 'migrations') .
" to be applied:</>\n"
);
}
foreach ($migrations as $migration) {
$nameLimit = $this->migrator->getMigrationNameLimit();
if (strlen($migration) > $nameLimit) {
$output->writeln(
"\n<fg=red>The migration name '$migration' is too long. Its not possible to apply " .
'this migration.</>'
);
return Command::INVALID;
}
$output->writeln("\t<fg=yellow>$migration</>");
}
/** @var QuestionHelper $helper */
$helper = $this->getHelper('question');
$question = new ConfirmationQuestion(
"\n<fg=cyan>Apply the above " . ($n === 1 ? 'migration y/n: ' : 'migrations y/n: '),
true
);
if ($helper->ask($input, $output, $question)) {
$instances = $this->migrationService->makeMigrations($migrations);
foreach ($instances as $instance) {
$this->updateRunner->run($instance);
}
$output->writeln(
"\n<fg=green> >>> $n " . ($n === 1 ? 'Migration was' : 'Migrations were') . " applied.</>\n"
);
$io->success('Updated successfully.');
}
$this->migrationService->databaseConnection();
return Command::SUCCESS;
}
}