Completed
Push — master ( 2b894b...836484 )
by Gaetano
05:34
created

ResumeCommand   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 106
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 7

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 13
lcom 2
cbo 7
dl 0
loc 106
ccs 0
cts 74
cp 0
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 16 1
C execute() 0 73 12
1
<?php
2
3
namespace Kaliop\eZMigrationBundle\Command;
4
5
use Kaliop\eZMigrationBundle\API\Value\Migration;
6
use Symfony\Component\Console\Input\InputInterface;
7
use Symfony\Component\Console\Output\OutputInterface;
8
use Symfony\Component\Console\Input\InputOption;
9
use Symfony\Component\Console\Question\ConfirmationQuestion;
10
/**
11
 * Command to resume suspended migrations.
12
 *
13
 * @todo add support for resuming a set based on path
14
 * @todo add support for the separate-process cli switch
15
 */
16
class ResumeCommand extends AbstractCommand
17
{
18
    /**
19
     * Set up the command.
20
     *
21
     * Define the name, options and help text.
22
     */
23
    protected function configure()
24
    {
25
        parent::configure();
26
27
        $this
28
            ->setName('kaliop:migration:resume')
29
            ->setDescription('Restarts any suspended migrations.')
30
            ->addOption('ignore-failures', 'i', InputOption::VALUE_NONE, "Keep resuming migrations even if one fails")
31
            ->addOption('no-interaction', 'n', InputOption::VALUE_NONE, "Do not ask any interactive question.")
32
            ->addOption('no-transactions', 'u', InputOption::VALUE_NONE, "Do not use a repository transaction to wrap each migration. Unsafe, but needed for legacy slot handlers")
33
            ->addOption('migration', 'm', InputOption::VALUE_REQUIRED, 'A single migration to resume (plain migration name).', null)
34
            ->setHelp(<<<EOT
35
The <info>kaliop:migration:resume</info> command allows you to resume any suspended migration
36
EOT
37
            );
38
    }
39
40
    /**
41
     * Execute the command.
42
     *
43
     * @param InputInterface $input
44
     * @param OutputInterface $output
45
     * @return null|int null or 0 if everything went fine, or an error code
46
     * @throws \Exception
47
     */
48
    protected function execute(InputInterface $input, OutputInterface $output)
49
    {
50
        $start = microtime(true);
51
52
        $this->getContainer()->get('ez_migration_bundle.step_executed_listener.tracing')->setOutput($output);
53
54
        $migrationService = $this->getMigrationService();
55
56
        $migrationName = $input->getOption('migration');
57
        if ($migrationName != null) {
58
            $suspendedMigration = $migrationService->getMigration($migrationName);
59
            if (!$suspendedMigration) {
60
                throw new \Exception("Migration '$migrationName' not found");
61
            }
62
            if ($suspendedMigration->status != Migration::STATUS_SUSPENDED) {
63
                throw new \Exception("Migration '$migrationName' is not suspended, can not resume it");
64
            }
65
66
            $suspendedMigrations = array($suspendedMigration);
67
        } else {
68
            $suspendedMigrations = $migrationService->getMigrationsByStatus(Migration::STATUS_SUSPENDED);
69
        };
70
71
        $output->writeln('<info>Found ' . count($suspendedMigrations) . ' suspended migrations</info>');
72
73
        if (!count($suspendedMigrations)) {
74
            $output->writeln('Nothing to do');
75
            return;
76
        }
77
78
        // ask user for confirmation to make changes
79
        if ($input->isInteractive() && !$input->getOption('no-interaction')) {
80
            $dialog = $this->getHelperSet()->get('question');
81
            if (!$dialog->ask(
82
                $input,
83
                $output,
84
                new ConfirmationQuestion('<question>Careful, the database will be modified. Do you want to continue Y/N ?</question>', false)
85
            )
86
            ) {
87
                $output->writeln('<error>Migration resuming cancelled!</error>');
88
                return 0;
89
            }
90
        }
91
92
        $executed = 0;
93
        $failed = 0;
94
95
        foreach($suspendedMigrations as $suspendedMigration) {
96
            $output->writeln("<info>Resuming {$suspendedMigration->name}</info>");
97
98
            try {
99
                $migrationService->resumeMigration($suspendedMigration, !$input->getOption('no-transactions'));
100
101
                $executed++;
102
            } catch (\Exception $e) {
103
                if ($input->getOption('ignore-failures')) {
104
                    $output->writeln("\n<error>Migration failed! Reason: " . $e->getMessage() . "</error>\n");
105
                    $failed++;
106
                    continue;
107
                }
108
                $output->writeln("\n<error>Migration aborted! Reason: " . $e->getMessage() . "</error>");
109
                return 1;
110
            }
111
        }
112
113
        $time = microtime(true) - $start;
114
        $output->writeln("Resumed $executed migrations, failed $failed");
115
        $output->writeln("Time taken: ".sprintf('%.2f', $time)." secs, memory: ".sprintf('%.2f', (memory_get_peak_usage(true) / 1000000)). ' MB');
116
117
        if ($failed) {
118
            return 2;
119
        }
120
    }
121
}
122