Completed
Push — master ( ad1d1c...ccece4 )
by Alexander
02:42
created

AbstractCommand::setSetting()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 4
ccs 0
cts 3
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 3
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\Command\AbstractCommand as BaseCommand;
15
use ConsoleHelpers\SVNBuddy\Config\AbstractConfigSetting;
16
use ConsoleHelpers\ConsoleKit\Config\ConfigEditor;
17
use ConsoleHelpers\SVNBuddy\Repository\Connector\Connector;
18
use ConsoleHelpers\SVNBuddy\Repository\RevisionLog\RevisionLog;
19
use ConsoleHelpers\SVNBuddy\Repository\RevisionLog\RevisionLogFactory;
20
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
21
use Symfony\Component\Console\Input\InputInterface;
22
use Symfony\Component\Console\Output\OutputInterface;
23
24
/**
25
 * Base command class.
26
 */
27
abstract class AbstractCommand extends BaseCommand
28
{
29
30
	/**
31
	 * Whatever "path" argument accepts repository urls.
32
	 *
33
	 * @var boolean
34
	 */
35
	protected $pathAcceptsUrl = false;
36
37
	/**
38
	 * Repository connector
39
	 *
40
	 * @var Connector
41
	 */
42
	protected $repositoryConnector;
43
44
	/**
45
	 * Working directory.
46
	 *
47
	 * @var string
48
	 */
49
	protected $workingDirectory = null;
50
51
	/**
52
	 * Revision logs by url
53
	 *
54
	 * @var RevisionLog[]
55
	 */
56
	private $_revisionLogs = array();
57
58
	/**
59
	 * Working copy paths.
60
	 *
61
	 * @var string
62
	 */
63
	private $_workingCopyPaths = array();
64
65
	/**
66
	 * Revision log factory.
67
	 *
68
	 * @var RevisionLogFactory
69
	 */
70
	private $_revisionLogFactory;
71
72
	/**
73
	 * Config editor.
74
	 *
75
	 * @var ConfigEditor
76
	 */
77
	private $_configEditor;
78
79
	/**
80
	 * {@inheritdoc}
81
	 */
82
	protected function initialize(InputInterface $input, OutputInterface $output)
83
	{
84
		$output->getFormatter()->setStyle('debug', new OutputFormatterStyle('white', 'magenta'));
85
86
		parent::initialize($input, $output);
87
	}
88
89
	/**
90
	 * Prepare dependencies.
91
	 *
92
	 * @return void
93
	 */
94
	protected function prepareDependencies()
95
	{
96
		parent::prepareDependencies();
97
98
		$container = $this->getContainer();
99
100
		$this->repositoryConnector = $container['repository_connector'];
101
		$this->_revisionLogFactory = $container['revision_log_factory'];
102
		$this->workingDirectory = $container['working_directory'];
103
		$this->_configEditor = $container['config_editor'];
104
	}
105
106
	/**
107
	 * Returns command setting value.
108
	 *
109
	 * @param string      $name         Name.
110
	 * @param string|null $command_name Command name to get settings from instead of current command.
111
	 *
112
	 * @return mixed
113
	 */
114
	protected function getSetting($name, $command_name = null)
115
	{
116
		return $this->_getConfigSetting($name, $command_name)->getValue();
117
	}
118
119
	/**
120
	 * Sets command setting value.
121
	 *
122
	 * @param string      $name         Name.
123
	 * @param mixed       $value        Value.
124
	 * @param string|null $command_name Command name to get settings from instead of current command.
125
	 *
126
	 * @return void
127
	 */
128
	protected function setSetting($name, $value, $command_name = null)
129
	{
130
		$this->_getConfigSetting($name, $command_name)->setValue($value);
131
	}
132
133
	/**
134
	 * Validates command setting usage.
135
	 *
136
	 * @param string      $name         Name.
137
	 * @param string|null $command_name Command name to get settings from instead of current command.
138
	 *
139
	 * @return AbstractConfigSetting
140
	 * @throws \LogicException When command don't have any config settings to provide.
141
	 * @throws \LogicException When config setting is not found.
142
	 */
143
	private function _getConfigSetting($name, $command_name = null)
144
	{
145
		// By default access own config settings.
146
		if ( !isset($command_name) ) {
147
			$command_name = $this->getName();
148
		}
149
150
		/** @var IConfigAwareCommand $command */
151
		$command = $this->getApplication()->get($command_name);
152
153
		if ( !($command instanceof IConfigAwareCommand) ) {
154
			throw new \LogicException('The "' . $command_name . '" command does not have any settings.');
155
		}
156
157
		foreach ( $command->getConfigSettings() as $config_setting ) {
158
			if ( $config_setting->getName() === $name ) {
159
				if ( $config_setting->isWithinScope(AbstractConfigSetting::SCOPE_WORKING_COPY) ) {
160
					$config_setting->setWorkingCopyUrl($this->getWorkingCopyUrl());
161
				}
162
163
				$config_setting->setEditor($this->_configEditor);
164
165
				return $config_setting;
166
			}
167
		}
168
169
		throw new \LogicException('The "' . $command_name . '" command doesn\'t have "' . $name . '" config setting.');
170
	}
171
172
	/**
173
	 * Prepare setting prefix.
174
	 *
175
	 * @param boolean $is_global Return global setting prefix.
176
	 *
177
	 * @return string
178
	 */
179
	protected function getConfigScope($is_global)
180
	{
181
		if ( $is_global ) {
182
			return 'global-settings.';
183
		}
184
185
		$wc_path = $this->getWorkingCopyPath();
186
		$wc_url = $this->repositoryConnector->getWorkingCopyUrl($wc_path);
187
		$wc_hash = substr(hash_hmac('sha1', $wc_url, 'svn-buddy'), 0, 8);
188
189
		return 'path-settings.' . $wc_hash . '.';
190
	}
191
192
	/**
193
	 * Returns revision log.
194
	 *
195
	 * @param string $repository_url Repository url.
196
	 *
197
	 * @return RevisionLog
198
	 */
199
	protected function getRevisionLog($repository_url)
200
	{
201
		if ( !isset($this->_revisionLogs[$repository_url]) ) {
202
			$this->_revisionLogs[$repository_url] = $this->_revisionLogFactory->getRevisionLog(
203
				$repository_url,
204
				$this->io
205
			);
206
		}
207
208
		return $this->_revisionLogs[$repository_url];
209
	}
210
211
	/**
212
	 * Transforms string into list.
213
	 *
214
	 * @param string $string    String.
215
	 * @param string $separator Separator.
216
	 *
217
	 * @return array
218
	 */
219
	protected function getList($string, $separator = ',')
220
	{
221
		return array_filter(array_map('trim', explode($separator, $string)));
222
	}
223
224
	/**
225
	 * Returns formatted list of records.
226
	 *
227
	 * @param array       $items         List of items.
228
	 * @param integer     $items_per_row Number of bugs displayed per row.
229
	 * @param string|null $color         Color.
230
	 *
231
	 * @return string
232
	 */
233
	protected function formatArray(array $items, $items_per_row, $color = null)
234
	{
235
		$bug_chunks = array_chunk($items, $items_per_row);
236
237
		$ret = array();
238
239
		if ( isset($color) ) {
240
			foreach ( $bug_chunks as $bug_chunk ) {
241
				$ret[] = '<fg=' . $color . '>' . implode('</>, <fg=' . $color . '>', $bug_chunk) . '</>';
242
			}
243
		}
244
		else {
245
			foreach ( $bug_chunks as $bug_chunk ) {
246
				$ret[] = implode(', ', $bug_chunk);
247
			}
248
		}
249
250
		return implode(',' . PHP_EOL, $ret);
251
	}
252
253
	/**
254
	 * Returns URL to the working copy.
255
	 *
256
	 * @return string
257
	 */
258
	protected function getWorkingCopyUrl()
259
	{
260
		return $this->repositoryConnector->getWorkingCopyUrl($this->getWorkingCopyPath());
261
	}
262
263
	/**
264
	 * Return working copy path.
265
	 *
266
	 * @return string
267
	 * @throws \RuntimeException When folder isn't a working copy.
268
	 */
269
	protected function getWorkingCopyPath()
270
	{
271
		$path = $this->getPath();
272
273
		if ( !in_array($path, $this->_workingCopyPaths) ) {
274
			if ( !$this->repositoryConnector->isUrl($path)
275
				&& !$this->repositoryConnector->isWorkingCopy($path)
276
			) {
277
				throw new \RuntimeException('The "' . $path . '" isn\'t a working copy.');
278
			}
279
280
			$this->_workingCopyPaths[] = $path;
281
		}
282
283
		return $path;
284
	}
285
286
	/**
287
	 * Returns all refs.
288
	 *
289
	 * @return array
290
	 */
291
	protected function getAllRefs()
292
	{
293
		$wc_url = $this->getWorkingCopyUrl();
294
		$revision_log = $this->getRevisionLog($wc_url);
295
296
		return $revision_log->find('refs', 'all_refs');
297
	}
298
299
	/**
300
	 * Return working copy path.
301
	 *
302
	 * @return string
303
	 * @throws \RuntimeException When url was given instead of path.
304
	 */
305
	protected function getPath()
306
	{
307
		// During auto-complete the IO isn't set.
308
		if ( !isset($this->io) ) {
309
			$path = '.';
310
		}
311
		else {
312
			$path = $this->io->getArgument('path');
313
		}
314
315
		if ( !$this->repositoryConnector->isUrl($path) ) {
316
			$path = realpath($path);
317
		}
318
		elseif ( !$this->pathAcceptsUrl ) {
319
			throw new \RuntimeException('The "path" argument must be a working copy path and not URL.');
320
		}
321
322
		return $path;
323
	}
324
325
}
326