RollbackCommand::configure()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 5
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 1
rs 10
1
<?php
2
3
/*
4
 * This file is part of the Magallanes package.
5
 *
6
 * (c) Andrés Montañez <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Mage\Command\BuiltIn\Releases;
13
14
use Mage\Task\TaskFactory;
15
use Mage\Runtime\Exception\RuntimeException;
16
use Symfony\Component\Process\Process;
17
use Symfony\Component\Console\Input\InputInterface;
18
use Symfony\Component\Console\Input\InputArgument;
19
use Symfony\Component\Console\Output\OutputInterface;
20
use Mage\Command\BuiltIn\DeployCommand;
21
22
/**
23
 * Command for Rolling Back a Releases
24
 *
25
 * @author Andrés Montañez <[email protected]>
26
 */
27
class RollbackCommand extends DeployCommand
28
{
29
    /**
30
     * Configure the Command
31
     */
32 63
    protected function configure(): void
33
    {
34
        $this
35 63
            ->setName('releases:rollback')
36 63
            ->setDescription('Rollback to a release on an environment')
37 63
            ->addArgument('environment', InputArgument::REQUIRED, 'Name of the environment to deploy to')
38 63
            ->addArgument('release', InputArgument::REQUIRED, 'The ID or the Index of the release to rollback to');
39
    }
40
41
    /**
42
     * Execute the Command
43
     */
44 4
    protected function execute(InputInterface $input, OutputInterface $output): int
45
    {
46 4
        $this->requireConfig();
47
48 4
        $output->writeln('Starting <fg=blue>Magallanes</>');
49 4
        $output->writeln('');
50
51
        try {
52 4
            $this->runtime->setEnvironment($input->getArgument('environment'));
53
54 3
            $strategy = $this->runtime->guessStrategy();
55 3
            $this->taskFactory = new TaskFactory($this->runtime);
56
57 3
            if (!$this->runtime->getEnvOption('releases', false)) {
58 1
                throw new RuntimeException('Releases are not enabled', 70);
59
            }
60
61 2
            $releaseToRollback = $input->getArgument('release');
62 2
            if ($this->checkReleaseAvailability($releaseToRollback) === false) {
63 1
                throw new RuntimeException(
64 1
                    sprintf('Release "%s" is not available on all hosts', $releaseToRollback),
65
                    72
66
                );
67
            }
68
69 1
            $this->runtime->setReleaseId($releaseToRollback)->setRollback(true);
70
71 1
            $output->writeln(sprintf('    Environment: <fg=green>%s</>', $this->runtime->getEnvironment()));
72 1
            $this->log(sprintf('Environment: %s', $this->runtime->getEnvironment()));
73
74 1
            $output->writeln(sprintf('    Rollback to Release Id: <fg=green>%s</>', $this->runtime->getReleaseId()));
75 1
            $this->log(sprintf('Release ID: %s', $this->runtime->getReleaseId()));
76
77 1
            if ($this->runtime->getConfigOption('log_file', false)) {
78 1
                $output->writeln(sprintf('    Logfile: <fg=green>%s</>', $this->runtime->getConfigOption('log_file')));
79
            }
80
81 1
            $output->writeln(sprintf('    Strategy: <fg=green>%s</>', $strategy->getName()));
82
83 1
            $output->writeln('');
84 1
            $this->runDeployment($output, $strategy);
85 3
        } catch (RuntimeException $exception) {
86 3
            $output->writeln(sprintf('<error>%s</error>', $exception->getMessage()));
87 3
            $this->statusCode = $exception->getCode();
88
        }
89
90 4
        $output->writeln('Finished <fg=blue>Magallanes</>');
91
92 4
        return intval($this->statusCode);
93
    }
94
95
    /**
96
     * Check if the provided Release ID is available in all hosts
97
     */
98 2
    protected function checkReleaseAvailability(string $releaseToRollback): bool
99
    {
100 2
        $hosts = $this->runtime->getEnvOption('hosts');
101 2
        $hostPath = rtrim($this->runtime->getEnvOption('host_path'), '/');
102
103 2
        $availableInHosts = 0;
104 2
        foreach ($hosts as $host) {
105 2
            $releases = [];
106 2
            $this->runtime->setWorkingHost($host);
107
108
            // Get List of Releases
109 2
            $cmdListReleases = sprintf('ls -1 %s/releases', $hostPath);
110
111
            /** @var Process $process */
112 2
            $process = $this->runtime->runRemoteCommand($cmdListReleases, false);
113 2
            if ($process->isSuccessful()) {
114 2
                $releases = explode("\n", trim($process->getOutput()));
115 2
                rsort($releases);
116
            }
117
118 2
            if (in_array($releaseToRollback, $releases)) {
119 2
                $availableInHosts++;
120
            }
121
122 2
            $this->runtime->setWorkingHost(null);
123
        }
124
125 2
        if ($availableInHosts === count($hosts)) {
126 1
            return (bool) $releaseToRollback;
127
        }
128
129 1
        return false;
130
    }
131
}
132