Completed
Push — master ( 38d497...203381 )
by Alexander
03:11
created

SelfUpdateCommand::configure()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 28
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 2
Metric Value
c 2
b 0
f 2
dl 0
loc 28
ccs 0
cts 22
cp 0
rs 8.8571
cc 1
eloc 21
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\Config\ConfigEditor;
15
use ConsoleHelpers\ConsoleKit\Exception\CommandException;
16
use Humbug\SelfUpdate\Strategy\GithubStrategy;
17
use Humbug\SelfUpdate\Strategy\ShaStrategy;
18
use Humbug\SelfUpdate\Strategy\StrategyInterface;
19
use Humbug\SelfUpdate\Updater;
20
use Symfony\Component\Console\Input\InputInterface;
21
use Symfony\Component\Console\Input\InputOption;
22
use Symfony\Component\Console\Output\OutputInterface;
23
24
class SelfUpdateCommand extends AbstractCommand
25
{
26
27
	const UPDATE_CHANNEL_SNAPSHOT = 'snapshot';
28
29
	const UPDATE_CHANNEL_STABLE = 'stable';
30
31
	const UPDATE_SERVER_URL = 'https://svn-buddy-updater.herokuapp.com';
32
33
	/**
34
	 * Config editor.
35
	 *
36
	 * @var ConfigEditor
37
	 */
38
	private $_configEditor;
39
40
	/**
41
	 * Path, where to store backups.
42
	 *
43
	 * @var string
44
	 */
45
	private $_backupsPath;
46
47
	/**
48
	 * {@inheritdoc}
49
	 */
50
	protected function configure()
51
	{
52
		$this
53
			->setName('self-update')
54
			->setDescription(
55
				'Updates application to most recent version in a given stability channel'
56
			)
57
			->addOption(
58
				'rollback',
59
				'r',
60
				InputOption::VALUE_NONE,
61
				'Revert to an older installation of application'
62
			)
63
			->addOption(
64
				'stable',
65
				null,
66
				InputOption::VALUE_NONE,
67
				'Force an update to the stable channel'
68
			)
69
			->addOption(
70
				'snapshot',
71
				null,
72
				InputOption::VALUE_NONE,
73
				'Force an update to the snapshot channel'
74
			);
75
76
		parent::configure();
77
	}
78
79
	/**
80
	 * Prepare dependencies.
81
	 *
82
	 * @return void
83
	 */
84
	protected function prepareDependencies()
85
	{
86
		parent::prepareDependencies();
87
88
		$container = $this->getContainer();
89
90
		$this->_configEditor = $container['config_editor'];
91
		$this->_backupsPath = $container['working_directory'] . '/backups';
92
93
		if ( !file_exists($this->_backupsPath) ) {
94
			mkdir($this->_backupsPath, 0777, true);
95
		}
96
	}
97
98
	/**
99
	 * {@inheritdoc}
100
	 */
101
	protected function execute(InputInterface $input, OutputInterface $output)
102
	{
103
		if ( $this->io->getOption('rollback') ) {
104
			$this->processRollback();
105
		}
106
		else {
107
			$this->processUpdate();
108
		}
109
	}
110
111
	/**
112
	 * Returns update strategy.
113
	 *
114
	 * @return StrategyInterface
115
	 * @throws CommandException When update channel cannot be found.
116
	 */
117
	protected function getUpdateStrategy()
118
	{
119
		$update_channel = $this->getUpdateChannel();
120
121
		if ( $update_channel === self::UPDATE_CHANNEL_STABLE ) {
122
			$update_strategy = new GithubStrategy();
123
			$update_strategy->setPackageName('console-helpers/svn-buddy');
124
			$update_strategy->setPharName('svn-buddy.phar');
125
			$update_strategy->setCurrentLocalVersion($this->getApplication()->getVersion());
126
127
			return $update_strategy;
128
		}
129
130
		$versions = json_decode(
131
			humbug_get_contents(self::UPDATE_SERVER_URL . '/versions'),
132
			true
133
		);
134
135
		if ( !isset($versions[$update_channel]) ) {
136
			throw new CommandException('The "' . $update_channel . '" update channel not found.');
137
		}
138
139
		$update_strategy = new ShaStrategy();
140
		$update_strategy->setPharUrl(self::UPDATE_SERVER_URL . $versions[$update_channel]['path']);
141
		$update_strategy->setVersionUrl(self::UPDATE_SERVER_URL . $versions[$update_channel]['path'] . '.sig');
142
143
		return $update_strategy;
144
	}
145
146
	/**
147
	 * Returns update channel.
148
	 *
149
	 * @return string
150
	 */
151
	protected function getUpdateChannel()
152
	{
153
		if ( $this->io->getOption('stable') ) {
154
			$this->_configEditor->set('update-channel', self::UPDATE_CHANNEL_STABLE);
155
		}
156
157
		if ( $this->io->getOption('snapshot') ) {
158
			$this->_configEditor->set('update-channel', self::UPDATE_CHANNEL_SNAPSHOT);
159
		}
160
161
		return $this->_configEditor->get('update-channel');
162
	}
163
164
	/**
165
	 * Processes rollback.
166
	 *
167
	 * @return void
168
	 * @throws CommandException When rollback failed.
169
	 */
170
	protected function processRollback()
171
	{
172
		$updater = new Updater(null, false);
173
174
		if ( !$updater->rollback() ) {
175
			throw new CommandException('Failed to restore previous version.');
176
		}
177
178
		$this->io->writeln('Previous version restored.');
179
	}
180
181
	/**
182
	 * Processes update.
183
	 *
184
	 * @return void
185
	 */
186
	protected function processUpdate()
187
	{
188
		$updater = new Updater(null, false);
189
		$updater->setStrategyObject($this->getUpdateStrategy());
190
191
		if ( !$updater->update() ) {
192
			$this->io->writeln('Already using latest version ("' . $this->getUpdateChannel() . '" channel).');
193
		}
194
		else {
195
			$this->io->writeln('Updated to latest version ("' . $this->getUpdateChannel() . '" channel).');
196
		}
197
	}
198
199
}
200