Passed
Push — master ( 49e198...27ddf9 )
by Alexander
16:42 queued 05:33
created

AbstractCommand::_showAppUpdateBanner()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 12
c 0
b 0
f 0
dl 0
loc 19
ccs 0
cts 13
cp 0
rs 9.8666
cc 2
nc 2
nop 1
crap 6
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\Command\AbstractCommand as BaseCommand;
15
use ConsoleHelpers\ConsoleKit\Exception\CommandException;
16
use ConsoleHelpers\SVNBuddy\Config\CommandConfig;
17
use ConsoleHelpers\SVNBuddy\Repository\Connector\Connector;
18
use ConsoleHelpers\SVNBuddy\Repository\RevisionLog\RevisionLog;
19
use ConsoleHelpers\SVNBuddy\Repository\RevisionLog\RevisionLogFactory;
20
use ConsoleHelpers\SVNBuddy\Repository\WorkingCopyResolver;
21
use ConsoleHelpers\SVNBuddy\Updater\UpdateManager;
22
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
23
use Symfony\Component\Console\Input\ArgvInput;
24
use Symfony\Component\Console\Input\InputInterface;
25
use Symfony\Component\Console\Output\OutputInterface;
26
27
/**
28
 * Base command class.
29
 */
30
abstract class AbstractCommand extends BaseCommand
31
{
32
33
	/**
34
	 * Raw path.
35
	 *
36
	 * @var string
37
	 */
38
	private $_rawPath;
39
40
	/**
41
	 * Whatever "path" argument accepts repository urls.
42
	 *
43
	 * @var boolean
44
	 */
45
	protected $pathAcceptsUrl = false;
46
47
	/**
48
	 * Repository connector
49
	 *
50
	 * @var Connector
51
	 */
52
	protected $repositoryConnector;
53
54
	/**
55
	 * Working directory.
56
	 *
57
	 * @var string
58
	 */
59
	protected $workingDirectory = null;
60
61
	/**
62
	 * Working copy resolver.
63
	 *
64
	 * @var WorkingCopyResolver
65
	 */
66
	private $_workingCopyResolver = null;
67
68
	/**
69
	 * Revision log factory.
70
	 *
71
	 * @var RevisionLogFactory
72
	 */
73
	private $_revisionLogFactory;
74
75
	/**
76
	 * Command config.
77
	 *
78
	 * @var CommandConfig
79
	 */
80
	private $_commandConfig;
81
82
	/**
83
	 * Update manager.
84
	 *
85
	 * @var UpdateManager
86
	 */
87
	private $_updateManager;
88
89
	/**
90
	 * {@inheritdoc}
91
	 *
92
	 * @throws \RuntimeException When url was given instead of path.
93
	 */
94
	protected function initialize(InputInterface $input, OutputInterface $output)
95
	{
96
		$this->_rawPath = null;
97
		$output->getFormatter()->setStyle('debug', new OutputFormatterStyle('white', 'magenta'));
98
99
		parent::initialize($input, $output);
100
101
		// Only apply check for commands, that accept working copy path.
102
		if ( $input->hasArgument('path') ) {
103
			if ( !$this->pathAcceptsUrl && $this->repositoryConnector->isUrl($this->getRawPath()) ) {
104
				throw new \RuntimeException('The "path" argument must be a working copy path and not URL.');
105
			}
106
		}
107
108
		if ( $this->checkForAppUpdates($input) ) {
109
			$this->_showAppUpdateBanner($output);
110
		}
111
	}
112
113
	/**
114
	 * Allow showing update banner.
115
	 *
116
	 * @param InputInterface $input Input.
117
	 *
118
	 * @return boolean
119
	 */
120
	protected function checkForAppUpdates(InputInterface $input)
121
	{
122
		// Show update banner only for outer command invoked by user and not sub-commands.
123
		return $input instanceof ArgvInput;
124
	}
125
126
	/**
127
	 * Shows application update banner.
128
	 *
129
	 * @param OutputInterface $output Output.
130
	 *
131
	 * @return void
132
	 */
133
	private function _showAppUpdateBanner(OutputInterface $output)
134
	{
135
		$new_version = $this->_updateManager->getNewVersion();
136
137
		if ( !strlen($new_version) ) {
138
			return;
139
		}
140
141
		$message = sprintf(
142
			'  Update available. Run "%s self-update" to upgrade.  ',
143
			$_SERVER['argv'][0]
144
		);
145
		$line_length = mb_strlen($message);
146
147
		$output->writeln(array(
148
			'<fg=white;bg=blue>' . str_repeat(' ', $line_length) . '</>',
149
			'<fg=white;bg=blue>' . $message . '</>',
150
			'<fg=white;bg=blue>' . str_repeat(' ', $line_length) . '</>',
151
			'',
152
		));
153
	}
154
155
	/**
156
	 * Prepare dependencies.
157
	 *
158
	 * @return void
159
	 */
160
	protected function prepareDependencies()
161
	{
162
		parent::prepareDependencies();
163
164
		$container = $this->getContainer();
165
166
		$this->_workingCopyResolver = $container['working_copy_resolver'];
167
		$this->repositoryConnector = $container['repository_connector'];
168
		$this->_revisionLogFactory = $container['revision_log_factory'];
169
		$this->workingDirectory = $container['working_directory'];
170
		$this->_commandConfig = $container['command_config'];
171
		$this->_updateManager = $container['update_manager'];
172
	}
173
174
	/**
175
	 * @inheritDoc
176
	 *
177
	 * @throws CommandException When command exception is caught.
178
	 */
179
	public function run(InputInterface $input, OutputInterface $output)
180
	{
181
		try {
182
			return parent::run($input, $output);
183
		}
184
		catch ( CommandException $e ) {
185
			$this->io->notify();
186
			throw $e;
187
		}
188
	}
189
190
	/**
191
	 * Returns command setting value.
192
	 *
193
	 * @param string $name Name.
194
	 *
195
	 * @return mixed
196
	 */
197
	protected function getSetting($name)
198
	{
199
		return $this->_commandConfig->getSettingValue($name, $this, $this->getRawPath());
200
	}
201
202
	/**
203
	 * Sets command setting value.
204
	 *
205
	 * @param string $name  Name.
206
	 * @param mixed  $value Value.
207
	 *
208
	 * @return void
209
	 */
210
	protected function setSetting($name, $value)
211
	{
212
		$this->_commandConfig->setSettingValue($name, $this, $this->getRawPath(), $value);
213
	}
214
215
	/**
216
	 * Returns revision log.
217
	 *
218
	 * @param string $repository_url Repository url.
219
	 *
220
	 * @return RevisionLog
221
	 */
222
	protected function getRevisionLog($repository_url)
223
	{
224
		return $this->_revisionLogFactory->getRevisionLog($repository_url, $this->io);
225
	}
226
227
	/**
228
	 * Transforms string into list.
229
	 *
230
	 * @param string $string    String.
231
	 * @param string $separator Separator.
232
	 *
233
	 * @return array
234
	 */
235
	protected function getList($string, $separator = ',')
236
	{
237
		return array_filter(array_map('trim', explode($separator, $string)));
238
	}
239
240
	/**
241
	 * Returns URL to the working copy.
242
	 *
243
	 * @return string
244
	 */
245
	protected function getWorkingCopyUrl()
246
	{
247
		return $this->_workingCopyResolver->getWorkingCopyUrl($this->getRawPath());
248
	}
249
250
	/**
251
	 * Return working copy path.
252
	 *
253
	 * @return string
254
	 */
255
	protected function getWorkingCopyPath()
256
	{
257
		return $this->_workingCopyResolver->getWorkingCopyPath($this->getRawPath());
258
	}
259
260
	/**
261
	 * Returns all refs.
262
	 *
263
	 * @return array
264
	 */
265
	protected function getAllRefs()
266
	{
267
		$wc_url = $this->getWorkingCopyUrl();
268
		$revision_log = $this->getRevisionLog($wc_url);
269
270
		return $revision_log->find('refs', 'all_refs');
271
	}
272
273
	/**
274
	 * Returns working copy path as used specified it.
275
	 *
276
	 * @return string
277
	 */
278
	protected function getRawPath()
279
	{
280
		if ( !isset($this->_rawPath) ) {
281
			// FIXME: During auto-complete working copy at CWD is used regardless of given path.
282
			if ( !isset($this->io) ) {
283
				$this->_rawPath = '.';
284
			}
285
			else {
286
				$this->_rawPath = $this->io->getArgument('path');
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->io->getArgument('path') can also be of type string[]. However, the property $_rawPath is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
287
			}
288
		}
289
290
		return $this->_rawPath;
291
	}
292
293
}
294