1
|
|
|
<?php |
2
|
|
|
/* |
3
|
|
|
* This file is part of the Magallanes package. |
4
|
|
|
* |
5
|
|
|
* (c) Andrés Montañez <[email protected]> |
6
|
|
|
* |
7
|
|
|
* For the full copyright and license information, please view the LICENSE |
8
|
|
|
* file that was distributed with this source code. |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
namespace Mage\Command\BuiltIn\Releases; |
12
|
|
|
|
13
|
|
|
use Mage\Utils; |
14
|
|
|
use Mage\Runtime\Exception\RuntimeException; |
15
|
|
|
use Symfony\Component\Process\Process; |
16
|
|
|
use Symfony\Component\Console\Input\InputInterface; |
17
|
|
|
use Symfony\Component\Console\Input\InputArgument; |
18
|
|
|
use Symfony\Component\Console\Output\OutputInterface; |
19
|
|
|
use Mage\Command\AbstractCommand; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* Command for Listing all Releases |
23
|
|
|
* |
24
|
|
|
* @author Andrés Montañez <[email protected]> |
25
|
|
|
*/ |
26
|
|
|
class ListCommand extends AbstractCommand |
27
|
|
|
{ |
28
|
|
|
/** |
29
|
|
|
* @var int |
30
|
|
|
*/ |
31
|
|
|
protected $statusCode = 0; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* Configure the Command |
35
|
|
|
*/ |
36
|
|
|
protected function configure() |
37
|
|
|
{ |
38
|
|
|
$this |
39
|
|
|
->setName('releases:list') |
40
|
|
|
->setDescription('List the releases on an environment') |
41
|
|
|
->addArgument('environment', InputArgument::REQUIRED, 'Name of the environment to deploy to') |
42
|
|
|
; |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Execute the Command |
47
|
|
|
* |
48
|
|
|
* @param InputInterface $input |
49
|
|
|
* @param OutputInterface $output |
50
|
|
|
* @return int|mixed |
51
|
|
|
*/ |
52
|
|
|
protected function execute(InputInterface $input, OutputInterface $output) |
53
|
|
|
{ |
54
|
|
|
$this->requireConfig(); |
55
|
|
|
|
56
|
|
|
$utils = new Utils(); |
57
|
|
|
$output->writeln('Starting <fg=blue>Magallanes</>'); |
58
|
|
|
$output->writeln(''); |
59
|
|
|
|
60
|
|
|
try { |
61
|
|
|
$this->runtime->setEnvironment($input->getArgument('environment')); |
|
|
|
|
62
|
|
|
|
63
|
|
|
if (!$this->runtime->getEnvOption('releases', false)) { |
64
|
|
|
throw new RuntimeException('Releases are not enabled', 70); |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
$output->writeln(sprintf(' Environment: <fg=green>%s</>', $this->runtime->getEnvironment())); |
68
|
|
|
$this->log(sprintf('Environment: %s', $this->runtime->getEnvironment())); |
69
|
|
|
|
70
|
|
View Code Duplication |
if ($this->runtime->getConfigOption('log_file', false)) { |
|
|
|
|
71
|
|
|
$output->writeln(sprintf(' Logfile: <fg=green>%s</>', $this->runtime->getConfigOption('log_file'))); |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
$output->writeln(''); |
75
|
|
|
|
76
|
|
|
$hosts = $this->runtime->getEnvOption('hosts'); |
77
|
|
|
if (!is_array($hosts) && !$hosts instanceof \Countable) { |
78
|
|
|
$hosts = []; |
79
|
|
|
} |
80
|
|
|
if (count($hosts) == 0) { |
81
|
|
|
$output->writeln('No hosts defined'); |
82
|
|
|
$output->writeln(''); |
83
|
|
|
} else { |
84
|
|
|
$hostPath = rtrim($this->runtime->getEnvOption('host_path'), '/'); |
85
|
|
|
|
86
|
|
|
foreach ($hosts as $host) { |
|
|
|
|
87
|
|
|
$this->runtime->setWorkingHost($host); |
88
|
|
|
|
89
|
|
|
// Get List of Releases |
90
|
|
|
$cmdListReleases = sprintf('ls -1 %s/releases', $hostPath); |
91
|
|
|
|
92
|
|
|
/** @var Process $process */ |
93
|
|
|
$process = $this->runtime->runRemoteCommand($cmdListReleases, false); |
94
|
|
|
if (!$process->isSuccessful()) { |
95
|
|
|
throw new RuntimeException(sprintf('Unable to retrieve releases from host "%s"', $host), 80); |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
$releases = []; |
99
|
|
|
if (trim($process->getOutput()) != '') { |
100
|
|
|
$releases = explode(PHP_EOL, trim($process->getOutput())); |
101
|
|
|
rsort($releases); |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
if (count($releases) == 0) { |
105
|
|
|
$output->writeln(sprintf(' No releases available on host <fg=black;options=bold>%s</>:', $host)); |
106
|
|
|
} else { |
107
|
|
|
// Get Current Release |
108
|
|
|
$cmdCurrentRelease = sprintf('readlink -f %s/current', $hostPath); |
109
|
|
|
|
110
|
|
|
/** @var Process $process */ |
111
|
|
|
$process = $this->runtime->runRemoteCommand($cmdCurrentRelease, false); |
112
|
|
|
if (!$process->isSuccessful()) { |
113
|
|
|
throw new RuntimeException(sprintf('Unable to retrieve current release from host "%s"', $host), 85); |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
$currentReleaseId = explode('/', trim($process->getOutput())); |
117
|
|
|
$currentReleaseId = $currentReleaseId[count($currentReleaseId) - 1]; |
118
|
|
|
|
119
|
|
|
$output->writeln(sprintf(' Releases on host <fg=black;options=bold>%s</>:', $host)); |
120
|
|
|
|
121
|
|
|
foreach ($releases as $releaseId) { |
122
|
|
|
$releaseDate = $utils->getReleaseDate($releaseId); |
123
|
|
|
|
124
|
|
|
$output->write(sprintf(' Release ID: <fg=magenta>%s</> - Date: <fg=black;options=bold>%s</> [%s]', |
125
|
|
|
$releaseId, |
126
|
|
|
$releaseDate->format('Y-m-d H:i:s'), |
127
|
|
|
$utils->getTimeDiff($releaseDate) |
128
|
|
|
)); |
129
|
|
|
|
130
|
|
|
if ($releaseId == $currentReleaseId) { |
131
|
|
|
$output->writeln(' <fg=red;options=bold>[current]</>'); |
132
|
|
|
} else { |
133
|
|
|
$output->writeln(''); |
134
|
|
|
} |
135
|
|
|
} |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
$this->runtime->setWorkingHost(null); |
139
|
|
|
$output->writeln(''); |
140
|
|
|
} |
141
|
|
|
} |
142
|
|
|
} catch (RuntimeException $exception) { |
143
|
|
|
$output->writeln(sprintf('<error>%s</error>', $exception->getMessage())); |
144
|
|
|
$this->statusCode = $exception->getCode(); |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
$output->writeln('Finished <fg=blue>Magallanes</>'); |
148
|
|
|
|
149
|
|
|
return $this->statusCode; |
150
|
|
|
} |
151
|
|
|
} |
152
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.