Issues (155)

src/SVNBuddy/Command/AbstractCommand.php (1 issue)

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
	 * Accent style.
63
	 *
64
	 * @var string
65
	 */
66
	protected $accentStyle;
67
68
	/**
69
	 * Working copy resolver.
70
	 *
71
	 * @var WorkingCopyResolver
72
	 */
73
	private $_workingCopyResolver = null;
74
75
	/**
76
	 * Revision log factory.
77
	 *
78
	 * @var RevisionLogFactory
79
	 */
80
	private $_revisionLogFactory;
81
82
	/**
83
	 * Command config.
84
	 *
85
	 * @var CommandConfig
86
	 */
87
	private $_commandConfig;
88
89
	/**
90
	 * Update manager.
91
	 *
92
	 * @var UpdateManager
93
	 */
94
	private $_updateManager;
95
96
	/**
97
	 * {@inheritdoc}
98
	 *
99
	 * @throws \RuntimeException When url was given instead of path.
100
	 */
101
	protected function initialize(InputInterface $input, OutputInterface $output)
102
	{
103
		$this->_rawPath = null;
104
		$output->getFormatter()->setStyle('debug', new OutputFormatterStyle('white', 'magenta'));
105
106
		parent::initialize($input, $output);
107
108
		// Only apply check for commands, that accept working copy path.
109
		if ( $input->hasArgument('path') ) {
110
			if ( !$this->pathAcceptsUrl && $this->repositoryConnector->isUrl($this->getRawPath()) ) {
111
				throw new \RuntimeException('The "path" argument must be a working copy path and not URL.');
112
			}
113
		}
114
115
		if ( $this->checkForAppUpdates($input) ) {
116
			$this->_showAppUpdateBanner($output);
117
		}
118
	}
119
120
	/**
121
	 * Allow showing update banner.
122
	 *
123
	 * @param InputInterface $input Input.
124
	 *
125
	 * @return boolean
126
	 */
127
	protected function checkForAppUpdates(InputInterface $input)
128
	{
129
		// Show update banner only for outer command invoked by user and not sub-commands.
130
		return $input instanceof ArgvInput;
131
	}
132
133
	/**
134
	 * Shows application update banner.
135
	 *
136
	 * @param OutputInterface $output Output.
137
	 *
138
	 * @return void
139
	 */
140
	private function _showAppUpdateBanner(OutputInterface $output)
141
	{
142
		$new_version = $this->_updateManager->getNewVersion();
143
144
		if ( !strlen($new_version) ) {
145
			return;
146
		}
147
148
		$message = sprintf(
149
			'  Update available. Run "%s self-update" to upgrade.  ',
150
			$_SERVER['argv'][0]
151
		);
152
		$line_length = mb_strlen($message);
153
154
		$output->writeln(array(
155
			'<fg=white;bg=blue>' . str_repeat(' ', $line_length) . '</>',
156
			'<fg=white;bg=blue>' . $message . '</>',
157
			'<fg=white;bg=blue>' . str_repeat(' ', $line_length) . '</>',
158
			'',
159
		));
160
	}
161
162
	/**
163
	 * Prepare dependencies.
164
	 *
165
	 * @return void
166
	 */
167
	protected function prepareDependencies()
168
	{
169
		parent::prepareDependencies();
170
171
		$container = $this->getContainer();
172
173
		$this->_workingCopyResolver = $container['working_copy_resolver'];
174
		$this->repositoryConnector = $container['repository_connector'];
175
		$this->_revisionLogFactory = $container['revision_log_factory'];
176
		$this->workingDirectory = $container['working_directory'];
177
		$this->_commandConfig = $container['command_config'];
178
		$this->_updateManager = $container['update_manager'];
179
180
		$this->accentStyle = $container['dark_theme'] ? 'fg=white;options=bold' : 'fg=cyan';
181
	}
182
183
	/**
184
	 * Returns command setting value.
185
	 *
186
	 * @param string $name Name.
187
	 *
188
	 * @return mixed
189
	 */
190
	protected function getSetting($name)
191
	{
192
		return $this->_commandConfig->getSettingValue($name, $this, $this->getRawPath());
193
	}
194
195
	/**
196
	 * Sets command setting value.
197
	 *
198
	 * @param string $name  Name.
199
	 * @param mixed  $value Value.
200
	 *
201
	 * @return void
202
	 */
203
	protected function setSetting($name, $value)
204
	{
205
		$this->_commandConfig->setSettingValue($name, $this, $this->getRawPath(), $value);
206
	}
207
208
	/**
209
	 * Returns revision log.
210
	 *
211
	 * @param string $repository_url Repository url.
212
	 *
213
	 * @return RevisionLog
214
	 */
215
	protected function getRevisionLog($repository_url)
216
	{
217
		return $this->_revisionLogFactory->getRevisionLog($repository_url, $this->io);
218
	}
219
220
	/**
221
	 * Transforms string into list.
222
	 *
223
	 * @param string $string    String.
224
	 * @param string $separator Separator.
225
	 *
226
	 * @return array
227
	 */
228
	protected function getList($string, $separator = ',')
229
	{
230
		return array_filter(array_map('trim', explode($separator, $string)));
231
	}
232
233
	/**
234
	 * Returns URL to the working copy.
235
	 *
236
	 * @return string
237
	 */
238
	protected function getWorkingCopyUrl()
239
	{
240
		return $this->_workingCopyResolver->getWorkingCopyUrl($this->getRawPath());
241
	}
242
243
	/**
244
	 * Return working copy path.
245
	 *
246
	 * @return string
247
	 */
248
	protected function getWorkingCopyPath()
249
	{
250
		return $this->_workingCopyResolver->getWorkingCopyPath($this->getRawPath());
251
	}
252
253
	/**
254
	 * Returns all refs.
255
	 *
256
	 * @return array
257
	 */
258
	protected function getAllRefs()
259
	{
260
		$wc_url = $this->getWorkingCopyUrl();
261
		$revision_log = $this->getRevisionLog($wc_url);
262
263
		return $revision_log->find('refs', 'all_refs');
264
	}
265
266
	/**
267
	 * Returns working copy path as used specified it.
268
	 *
269
	 * @return string
270
	 */
271
	protected function getRawPath()
272
	{
273
		if ( !isset($this->_rawPath) ) {
274
			// FIXME: During auto-complete working copy at CWD is used regardless of given path.
275
			if ( !isset($this->io) ) {
276
				$this->_rawPath = '.';
277
			}
278
			else {
279
				$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...
280
			}
281
		}
282
283
		return $this->_rawPath;
284
	}
285
286
}
287