SelfUpdateCommand::configure()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 39
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 5
Bugs 0 Features 0
Metric Value
eloc 30
c 5
b 0
f 0
dl 0
loc 39
ccs 0
cts 37
cp 0
rs 9.44
cc 1
nc 1
nop 0
crap 2
1
<?php
2
/**
3
 * This file is part of the SVN-Buddy library.
4
 * For the full copyright and license information, please view
5
 * the LICENSE file that was distributed with this source code.
6
 *
7
 * @copyright Alexander Obuhovich <[email protected]>
8
 * @link      https://github.com/console-helpers/svn-buddy
9
 */
10
11
namespace ConsoleHelpers\SVNBuddy\Command;
12
13
14
use ConsoleHelpers\ConsoleKit\Exception\CommandException;
15
use ConsoleHelpers\SVNBuddy\Process\ProcessFactory;
16
use ConsoleHelpers\SVNBuddy\Updater\Stability;
17
use ConsoleHelpers\SVNBuddy\Updater\UpdateManager;
18
use ConsoleHelpers\SVNBuddy\Updater\Updater;
19
use Symfony\Component\Console\Input\InputInterface;
20
use Symfony\Component\Console\Input\InputOption;
21
use Symfony\Component\Console\Output\OutputInterface;
22
23
class SelfUpdateCommand extends AbstractCommand
24
{
25
26
	/**
27
	 * Update manager.
28
	 *
29
	 * @var UpdateManager
30
	 */
31
	private $_updateManager;
32
33
	/**
34
	 * Process factory.
35
	 *
36
	 * @var ProcessFactory
37
	 */
38
	private $_processFactory;
39
40
	/**
41
	 * {@inheritdoc}
42
	 */
43
	protected function configure()
44
	{
45
		$this
46
			->setName('self-update')
47
			->setDescription(
48
				'Update application to most recent version'
49
			)
50
			->addOption(
51
				'rollback',
52
				'r',
53
				InputOption::VALUE_NONE,
54
				'Revert to an older version of the application'
55
			)
56
			->addOption(
57
				'stable',
58
				null,
59
				InputOption::VALUE_NONE,
60
				'Force an update to the stable channel'
61
			)
62
			->addOption(
63
				'snapshot',
64
				null,
65
				InputOption::VALUE_NONE,
66
				'Force an update to the snapshot channel'
67
			)
68
			->addOption(
69
				'preview',
70
				null,
71
				InputOption::VALUE_NONE,
72
				'Force an update to the preview channel'
73
			)
74
			->addOption(
75
				'check',
76
				null,
77
				InputOption::VALUE_NONE,
78
				'Checks for update availability'
79
			);
80
81
		parent::configure();
82
	}
83
84
	/**
85
	 * Prepare dependencies.
86
	 *
87
	 * @return void
88
	 */
89
	protected function prepareDependencies()
90
	{
91
		parent::prepareDependencies();
92
93
		$container = $this->getContainer();
94
95
		$this->_updateManager = $container['update_manager'];
96
		$this->_processFactory = $container['process_factory'];
97
	}
98
99
	/**
100
	 * Allow showing update banner.
101
	 *
102
	 * @param InputInterface $input Input.
103
	 *
104
	 * @return boolean
105
	 */
106
	protected function checkForAppUpdates(InputInterface $input)
107
	{
108
		return false;
109
	}
110
111
	/**
112
	 * {@inheritdoc}
113
	 */
114
	protected function execute(InputInterface $input, OutputInterface $output)
115
	{
116
		$this->changeUpdateChannel();
117
118
		if ( $this->io->getOption('rollback') ) {
119
			$this->processRollback();
120
		}
121
		elseif ( $this->io->getOption('check') ) {
122
			$this->processCheck();
123
		}
124
		else {
125
			$this->processUpdate();
126
		}
127
	}
128
129
	/**
130
	 * Changes update channel.
131
	 *
132
	 * @return void
133
	 */
134
	protected function changeUpdateChannel()
135
	{
136
		if ( $this->io->getOption('stable') ) {
137
			$this->_updateManager->setUpdateChannel(Stability::STABLE);
138
		}
139
140
		if ( $this->io->getOption('snapshot') ) {
141
			$this->_updateManager->setUpdateChannel(Stability::SNAPSHOT);
142
		}
143
144
		if ( $this->io->getOption('preview') ) {
145
			$this->_updateManager->setUpdateChannel(Stability::PREVIEW);
146
		}
147
	}
148
149
	/**
150
	 * Processes rollback.
151
	 *
152
	 * @return void
153
	 * @throws CommandException When rollback failed.
154
	 */
155
	protected function processRollback()
156
	{
157
		$updater = new Updater(null, false);
158
159
		// To get all needed classes autoloaded before phar gets overwritten.
160
		$this->getFreshVersion();
161
162
		if ( !$updater->rollback() ) {
163
			throw new CommandException('Failed to restore previous version.');
164
		}
165
166
		$this->io->writeln(
167
			'Rolling back to version <info>' . $this->getFreshVersion() . '</info>.'
168
		);
169
	}
170
171
	/**
172
	 * Returns fresh application version.
173
	 *
174
	 * @return string
175
	 */
176
	protected function getFreshVersion()
177
	{
178
		$output = $this->_processFactory
179
			->createCommandProcess('list', array('--format=xml'))
180
			->mustRun()
181
			->getOutput();
182
183
		$xml = new \SimpleXMLElement($output);
184
185
		return (string)$xml['version'];
186
	}
187
188
	/**
189
	 * Processes update.
190
	 *
191
	 * @return void
192
	 */
193
	protected function processUpdate()
194
	{
195
		$updater = $this->_updateManager->getUpdater();
196
197
		$this->io->write('Checking for updates ... ');
198
		$has_update = $updater->hasUpdate();
199
		$this->io->writeln('done');
200
201
		$update_channel = $this->_updateManager->getUpdateChannel();
202
203
		if ( !$has_update ) {
204
			$this->io->writeln(sprintf(
205
				'<info>You are already using version %s (%s channel).</info>',
206
				$updater->getNewVersion(),
207
				$update_channel
208
			));
209
210
			return;
211
		}
212
213
		$this->io->write(
214
			'Updating to version <info>' . $updater->getNewVersion() . '</info> (' . $update_channel . ' channel) ... '
215
		);
216
217
		$updater->update();
218
		$this->_updateManager->setNewVersion('');
219
220
		$this->io->writeln('done.');
221
222
		$this->io->writeln(sprintf(
223
			'Run <info>%s self-update --rollback</info> to return to version %s',
224
			$_SERVER['argv'][0],
225
			$updater->getOldVersion()
226
		));
227
	}
228
229
	/**
230
	 * Processes check.
231
	 *
232
	 * @return void
233
	 */
234
	protected function processCheck()
235
	{
236
		$updater = $this->_updateManager->getUpdater();
237
238
		$this->io->write('Checking for updates ... ');
239
		$has_update = $updater->hasUpdate();
240
		$this->io->writeln('done');
241
242
		$this->_updateManager->setNewVersion($has_update ? $updater->getNewVersion() : '');
243
	}
244
245
}
246