1
|
|
|
<?php |
2
|
|
|
namespace Kunstmaan\Skylab\Command; |
3
|
|
|
|
4
|
|
|
use Humbug\SelfUpdate\Strategy\GithubStrategy; |
5
|
|
|
use Humbug\SelfUpdate\Strategy\ShaStrategy; |
6
|
|
|
use Humbug\SelfUpdate\Updater; |
7
|
|
|
use Humbug\SelfUpdate\VersionParser; |
8
|
|
|
use Symfony\Component\Console\Input\InputOption; |
9
|
|
|
|
10
|
|
|
|
11
|
|
|
class SelfUpdateCommand extends AbstractCommand |
12
|
|
|
{ |
13
|
|
|
|
14
|
|
|
const VERSION_URL = 'https://s3-eu-west-1.amazonaws.com/kunstmaan-skylab/skylab.version'; |
15
|
|
|
const PHAR_URL = 'https://s3-eu-west-1.amazonaws.com/kunstmaan-skylab/skylab.phar'; |
16
|
|
|
const PACKAGE_NAME = 'kunstmaan/skylab'; |
17
|
|
|
const FILE_NAME = 'skylab.phar'; |
18
|
|
|
|
19
|
|
|
protected function configure() |
20
|
|
|
{ |
21
|
|
|
$this |
22
|
|
|
->addDefaults() |
23
|
|
|
->setName('self-update') |
24
|
|
|
->setDescription('Update skylab.phar to most recent stable, pre-release or development build.') |
25
|
|
|
->addOption( |
26
|
|
|
'dev', |
27
|
|
|
'd', |
28
|
|
|
InputOption::VALUE_NONE, |
29
|
|
|
'Update to most recent development build of Skylab.' |
30
|
|
|
) |
31
|
|
|
->addOption( |
32
|
|
|
'non-dev', |
33
|
|
|
'N', |
34
|
|
|
InputOption::VALUE_NONE, |
35
|
|
|
'Update to most recent non-development (alpha/beta/stable) build of Skylab tagged on Github.' |
36
|
|
|
) |
37
|
|
|
->addOption( |
38
|
|
|
'pre', |
39
|
|
|
'p', |
40
|
|
|
InputOption::VALUE_NONE, |
41
|
|
|
'Update to most recent pre-release version of Skylab (alpha/beta/rc) tagged on Github.' |
42
|
|
|
) |
43
|
|
|
->addOption( |
44
|
|
|
'stable', |
45
|
|
|
's', |
46
|
|
|
InputOption::VALUE_NONE, |
47
|
|
|
'Update to most recent stable version of Skylab tagged on Github.' |
48
|
|
|
) |
49
|
|
|
->addOption( |
50
|
|
|
'rollback', |
51
|
|
|
'r', |
52
|
|
|
InputOption::VALUE_NONE, |
53
|
|
|
'Rollback to previous version of Skylab if available on filesystem.' |
54
|
|
|
) |
55
|
|
|
->addOption( |
56
|
|
|
'check', |
57
|
|
|
'c', |
58
|
|
|
InputOption::VALUE_NONE, |
59
|
|
|
'Checks what updates are available across all possible stability tracks.' |
60
|
|
|
) |
61
|
|
|
->setHelp(<<<EOT |
62
|
|
|
The <info>self-update</info> command will check if there is an updated skylab.phar released and updates if it is. |
63
|
|
|
|
64
|
|
|
<info>php skylab.phar self-update</info> |
65
|
|
|
|
66
|
|
|
EOT |
67
|
|
|
); |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
protected function doExecute() |
71
|
|
|
{ |
72
|
|
|
|
73
|
|
|
$parser = new VersionParser(); |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Check for ancilliary options |
77
|
|
|
*/ |
78
|
|
|
if ($this->input->getOption('rollback')) { |
79
|
|
|
$this->rollback(); |
80
|
|
|
return; |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
if ($this->input->getOption('check')) { |
84
|
|
|
$this->printAvailableUpdates(); |
85
|
|
|
return; |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
/** |
89
|
|
|
* Update to any specified stability option |
90
|
|
|
*/ |
91
|
|
|
if ($this->input->getOption('dev')) { |
92
|
|
|
$this->updateToDevelopmentBuild(); |
93
|
|
|
return; |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
if ($this->input->getOption('pre')) { |
97
|
|
|
$this->updateToPreReleaseBuild(); |
98
|
|
|
return; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
if ($this->input->getOption('stable')) { |
102
|
|
|
$this->updateToStableBuild(); |
103
|
|
|
return; |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
if ($this->input->getOption('non-dev')) { |
107
|
|
|
$this->updateToMostRecentNonDevRemote(); |
108
|
|
|
return; |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* If current build is stable, only update to more recent stable versions if available. User may specify |
113
|
|
|
* otherwise using options. |
114
|
|
|
*/ |
115
|
|
|
if ($parser->isStable($this->getApplication()->getVersion())) { |
116
|
|
|
$this->updateToStableBuild(); |
117
|
|
|
return; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* By default, update to most recent remote version regardless of stability. |
122
|
|
|
*/ |
123
|
|
|
$this->updateToMostRecentNonDevRemote(); |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
protected function getStableUpdater() |
127
|
|
|
{ |
128
|
|
|
$updater = new Updater(null, false); |
129
|
|
|
$updater->setStrategy(Updater::STRATEGY_GITHUB); |
130
|
|
|
return $this->getGithubReleasesUpdater($updater); |
131
|
|
|
} |
132
|
|
|
|
133
|
|
View Code Duplication |
protected function getPreReleaseUpdater() |
|
|
|
|
134
|
|
|
{ |
135
|
|
|
$updater = new Updater(null, false); |
136
|
|
|
$updater->setStrategy(Updater::STRATEGY_GITHUB); |
137
|
|
|
/** @var GithubStrategy $strategyInterface */ |
138
|
|
|
$strategyInterface = $updater->getStrategy(); |
139
|
|
|
$strategyInterface->setStability(GithubStrategy::UNSTABLE); |
140
|
|
|
return $this->getGithubReleasesUpdater($updater); |
141
|
|
|
} |
142
|
|
|
|
143
|
|
View Code Duplication |
protected function getMostRecentNonDevUpdater() |
|
|
|
|
144
|
|
|
{ |
145
|
|
|
$updater = new Updater(null, false); |
146
|
|
|
$updater->setStrategy(Updater::STRATEGY_GITHUB); |
147
|
|
|
/** @var GithubStrategy $strategyInterface */ |
148
|
|
|
$strategyInterface = $updater->getStrategy(); |
149
|
|
|
$strategyInterface->setStability(GithubStrategy::ANY); |
150
|
|
|
return $this->getGithubReleasesUpdater($updater); |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
protected function getGithubReleasesUpdater(Updater $updater) |
154
|
|
|
{ |
155
|
|
|
/** @var GithubStrategy $strategyInterface */ |
156
|
|
|
$strategyInterface = $updater->getStrategy(); |
157
|
|
|
$strategyInterface->setPackageName(self::PACKAGE_NAME); |
158
|
|
|
$strategyInterface->setPharName(self::FILE_NAME); |
159
|
|
|
$strategyInterface->setCurrentLocalVersion($this->getApplication()->getVersion()); |
160
|
|
|
return $updater; |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
protected function getDevelopmentUpdater() |
164
|
|
|
{ |
165
|
|
|
$updater = new Updater(null, false); |
166
|
|
|
/** @var ShaStrategy $strategyInterface */ |
167
|
|
|
$strategyInterface = $updater->getStrategy(); |
168
|
|
|
$strategyInterface->setPharUrl(self::PHAR_URL); |
169
|
|
|
$strategyInterface->setVersionUrl(self::VERSION_URL); |
170
|
|
|
return $updater; |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
protected function updateToStableBuild() |
174
|
|
|
{ |
175
|
|
|
$this->update($this->getStableUpdater()); |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
protected function updateToPreReleaseBuild() |
179
|
|
|
{ |
180
|
|
|
$this->update($this->getPreReleaseUpdater()); |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
protected function updateToMostRecentNonDevRemote() |
184
|
|
|
{ |
185
|
|
|
$this->update($this->getMostRecentNonDevUpdater()); |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
protected function updateToDevelopmentBuild() |
189
|
|
|
{ |
190
|
|
|
$this->update($this->getDevelopmentUpdater()); |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
protected function update(Updater $updater) |
194
|
|
|
{ |
195
|
|
|
$this->dialogProvider->logCommand("Updating Skylab"); |
196
|
|
|
try { |
197
|
|
|
$result = $updater->update(); |
198
|
|
|
|
199
|
|
|
$newVersion = $updater->getNewVersion(); |
200
|
|
|
$oldVersion = $updater->getOldVersion(); |
201
|
|
|
if (strlen($newVersion) == 40) { |
202
|
|
|
$newVersion = 'dev-' . $newVersion; |
203
|
|
|
} |
204
|
|
|
if (strlen($oldVersion) == 40) { |
205
|
|
|
$oldVersion = 'dev-' . $oldVersion; |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
if ($result) { |
209
|
|
|
$this->dialogProvider->logTask("Skylab has been updated from $oldVersion to $newVersion"); |
210
|
|
|
} else { |
211
|
|
|
$this->dialogProvider->logTask("Skylab is currently up to date at $oldVersion"); |
212
|
|
|
} |
213
|
|
|
} catch (\Exception $e) { |
214
|
|
|
$this->dialogProvider->logError("Error: " . $e->getMessage()); |
215
|
|
|
} |
216
|
|
|
$this->dialogProvider->logNotice('You can also select update stability using --dev, --pre (alpha/beta/rc) or --stable.'); |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
protected function rollback() |
220
|
|
|
{ |
221
|
|
|
$updater = new Updater; |
222
|
|
|
try { |
223
|
|
|
$result = $updater->rollback(); |
224
|
|
|
if ($result) { |
225
|
|
|
$this->dialogProvider->logTask("Skylab has been rolled back to prior version."); |
226
|
|
|
} else { |
227
|
|
|
$this->dialogProvider->logError("Rollback failed for reasons unknown."); |
228
|
|
|
} |
229
|
|
|
} catch (\Exception $e) { |
230
|
|
|
$this->dialogProvider->logError("Error: " . $e->getMessage()); |
231
|
|
|
} |
232
|
|
|
} |
233
|
|
|
|
234
|
|
|
protected function printAvailableUpdates() |
235
|
|
|
{ |
236
|
|
|
$this->printCurrentLocalVersion(); |
237
|
|
|
$this->printCurrentStableVersion(); |
238
|
|
|
$this->printCurrentPreReleaseVersion(); |
239
|
|
|
$this->printCurrentDevVersion(); |
240
|
|
|
$this->dialogProvider->logNotice('You can select update stability using --dev, --pre or --stable when self-updating.'); |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
protected function printCurrentLocalVersion() |
244
|
|
|
{ |
245
|
|
|
$this->dialogProvider->logTask("Your current local build version is: " . $this->getApplication()->getVersion()); |
246
|
|
|
} |
247
|
|
|
|
248
|
|
|
protected function printCurrentStableVersion() |
249
|
|
|
{ |
250
|
|
|
$this->printVersion($this->getStableUpdater()); |
251
|
|
|
} |
252
|
|
|
|
253
|
|
|
protected function printCurrentPreReleaseVersion() |
254
|
|
|
{ |
255
|
|
|
$this->printVersion($this->getPreReleaseUpdater()); |
256
|
|
|
} |
257
|
|
|
|
258
|
|
|
protected function printCurrentDevVersion() |
259
|
|
|
{ |
260
|
|
|
$this->printVersion($this->getDevelopmentUpdater()); |
261
|
|
|
} |
262
|
|
|
|
263
|
|
|
protected function printVersion(Updater $updater) |
264
|
|
|
{ |
265
|
|
|
$stability = 'stable'; |
266
|
|
|
$strategyInterface = $updater->getStrategy(); |
267
|
|
|
if ($strategyInterface instanceof ShaStrategy) { |
268
|
|
|
$stability = 'development'; |
269
|
|
|
} elseif ($strategyInterface instanceof GithubStrategy |
270
|
|
|
&& $strategyInterface->getStability() == GithubStrategy::UNSTABLE) { |
271
|
|
|
$stability = 'pre-release'; |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
try { |
275
|
|
|
if ($updater->hasUpdate()) { |
276
|
|
|
$this->dialogProvider->logTask("The current $stability build available remotely is: " . $updater->getNewVersion()); |
277
|
|
|
} elseif (false == $updater->getNewVersion()) { |
|
|
|
|
278
|
|
|
$this->dialogProvider->logTask("There are no $stability builds available."); |
279
|
|
|
} else { |
280
|
|
|
$this->dialogProvider->logTask("You have the current $stability build installed."); |
281
|
|
|
} |
282
|
|
|
} catch (\Exception $e) { |
283
|
|
|
$this->dialogProvider->logError("Error: " . $e->getMessage()); |
284
|
|
|
} |
285
|
|
|
} |
286
|
|
|
} |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.