Failed Conditions
Push — master ( fe778b...ae8928 )
by Alexander
02:48
created

LogCommand::completeOptionValues()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 0
cts 9
cp 0
rs 9.2
c 0
b 0
f 0
cc 4
eloc 9
nc 4
nop 2
crap 20
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\SVNBuddy\Config\AbstractConfigSetting;
15
use ConsoleHelpers\SVNBuddy\Config\IntegerConfigSetting;
16
use ConsoleHelpers\SVNBuddy\Config\RegExpsConfigSetting;
17
use ConsoleHelpers\ConsoleKit\Exception\CommandException;
18
use ConsoleHelpers\SVNBuddy\Repository\Parser\RevisionListParser;
19
use ConsoleHelpers\SVNBuddy\Repository\RevisionLog\RevisionLog;
20
use ConsoleHelpers\SVNBuddy\Repository\RevisionLog\RevisionPrinter;
21
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
22
use Symfony\Component\Console\Input\InputArgument;
23
use Symfony\Component\Console\Input\InputInterface;
24
use Symfony\Component\Console\Input\InputOption;
25
use Symfony\Component\Console\Output\OutputInterface;
26
27
class LogCommand extends AbstractCommand implements IAggregatorAwareCommand, IConfigAwareCommand
28
{
29
30
	const SETTING_LOG_LIMIT = 'log.limit';
31
32
	const SETTING_LOG_MESSAGE_LIMIT = 'log.message-limit';
33
34
	const SETTING_LOG_MERGE_CONFLICT_REGEXPS = 'log.merge-conflict-regexps';
35
36
	const ALL_REFS = 'all';
37
38
	/**
39
	 * Revision list parser.
40
	 *
41
	 * @var RevisionListParser
42
	 */
43
	private $_revisionListParser;
44
45
	/**
46
	 * Revision log
47
	 *
48
	 * @var RevisionLog
49
	 */
50
	private $_revisionLog;
51
52
	/**
53
	 * Revision printer.
54
	 *
55
	 * @var RevisionPrinter
56
	 */
57
	private $_revisionPrinter;
58
59
	/**
60
	 * Prepare dependencies.
61
	 *
62
	 * @return void
63
	 */
64
	protected function prepareDependencies()
65
	{
66
		parent::prepareDependencies();
67
68
		$container = $this->getContainer();
69
70
		$this->_revisionListParser = $container['revision_list_parser'];
71
		$this->_revisionPrinter = $container['revision_printer'];
72
	}
73
74
	/**
75
	 * {@inheritdoc}
76
	 */
77
	protected function configure()
78
	{
79
		$this->pathAcceptsUrl = true;
80
81
		$this
82
			->setName('log')
83
			->setDescription(
84
				'Show the log messages for a set of revisions, bugs, paths, refs, etc.'
85
			)
86
			->addArgument(
87
				'path',
88
				InputArgument::OPTIONAL,
89
				'Working copy path or URL',
90
				'.'
91
			)
92
			->addOption(
93
				'revisions',
94
				'r',
95
				InputOption::VALUE_REQUIRED,
96
				'List of revision(-s) and/or revision range(-s), e.g. <comment>53324</comment>, <comment>1224-4433</comment>'
97
			)
98
			->addOption(
99
				'bugs',
100
				'b',
101
				InputOption::VALUE_REQUIRED,
102
				'List of bug(-s), e.g. <comment>JRA-1234</comment>, <comment>43644</comment>'
103
			)
104
			->addOption(
105
				'refs',
106
				null,
107
				InputOption::VALUE_REQUIRED,
108
				'List of refs, e.g. <comment>trunk</comment>, <comment>branches/branch-name</comment>, <comment>tags/tag-name</comment> or <comment>all</comment> for all refs'
109
			)
110
			->addOption(
111
				'merges',
112
				null,
113
				InputOption::VALUE_NONE,
114
				'Show merge revisions only'
115
			)
116
			->addOption(
117
				'no-merges',
118
				null,
119
				InputOption::VALUE_NONE,
120
				'Hide merge revisions'
121
			)
122
			->addOption(
123
				'merged',
124
				null,
125
				InputOption::VALUE_NONE,
126
				'Shows only revisions, that were merged at least once'
127
			)
128
			->addOption(
129
				'not-merged',
130
				null,
131
				InputOption::VALUE_NONE,
132
				'Shows only revisions, that were not merged'
133
			)
134
			->addOption(
135
				'merged-by',
136
				null,
137
				InputOption::VALUE_REQUIRED,
138
				'Show revisions merged by list of revision(-s) and/or revision range(-s)'
139
			)
140
			->addOption(
141
				'action',
142
				null,
143
				InputOption::VALUE_REQUIRED,
144
				'Show revisions, whose paths were affected by specified action, e.g. <comment>A</comment>, <comment>M</comment>, <comment>R</comment>, <comment>D</comment>'
145
			)
146
			->addOption(
147
				'kind',
148
				null,
149
				InputOption::VALUE_REQUIRED,
150
				'Show revisions, whose paths match specified kind, e.g. <comment>dir</comment> or <comment>file</comment>'
151
			)
152
			->addOption(
153
				'with-details',
154
				'd',
155
				InputOption::VALUE_NONE,
156
				'Shows detailed revision information, e.g. paths affected'
157
			)
158
			->addOption(
159
				'with-summary',
160
				's',
161
				InputOption::VALUE_NONE,
162
				'Shows number of added/changed/removed paths in the revision'
163
			)
164
			->addOption(
165
				'with-refs',
166
				null,
167
				InputOption::VALUE_NONE,
168
				'Shows revision refs'
169
			)
170
			->addOption(
171
				'with-merge-oracle',
172
				null,
173
				InputOption::VALUE_NONE,
174
				'Shows number of paths in the revision, that can cause conflict upon merging'
175
			)
176
			->addOption(
177
				'with-merge-status',
178
				null,
179
				InputOption::VALUE_NONE,
180
				'Shows merge revisions affecting this revision'
181
			)
182
			->addOption(
183
				'max-count',
184
				null,
185
				InputOption::VALUE_REQUIRED,
186
				'Limit the number of revisions to output'
187
			);
188
189
		parent::configure();
190
	}
191
192
	/**
193
	 * Return possible values for the named option
194
	 *
195
	 * @param string            $optionName Option name.
196
	 * @param CompletionContext $context    Completion context.
197
	 *
198
	 * @return array
199
	 */
200
	public function completeOptionValues($optionName, CompletionContext $context)
201
	{
202
		$ret = parent::completeOptionValues($optionName, $context);
203
204
		if ( $optionName === 'refs' ) {
205
			return $this->getAllRefs();
206
		}
207
		elseif ( $optionName === 'action' ) {
208
			return $this->getAllActions();
209
		}
210
		elseif ( $optionName === 'kind' ) {
211
			return $this->getAllKinds();
212
		}
213
214
		return $ret;
215
	}
216
217
	/**
218
	 * {@inheritdoc}
219
	 */
220
	public function initialize(InputInterface $input, OutputInterface $output)
221
	{
222
		parent::initialize($input, $output);
223
224
		$this->_revisionLog = $this->getRevisionLog($this->getWorkingCopyUrl());
225
	}
226
227
	/**
228
	 * {@inheritdoc}
229
	 *
230
	 * @throws \RuntimeException When both "--bugs" and "--revisions" options were specified.
231
	 * @throws CommandException When specified revisions are not present in current project.
232
	 * @throws CommandException When project contains no associated revisions.
233
	 */
234
	protected function execute(InputInterface $input, OutputInterface $output)
235
	{
236
		$searching_start = microtime(true);
237
		$bugs = $this->getList($this->io->getOption('bugs'));
238
		$revisions = $this->getList($this->io->getOption('revisions'));
239
240
		if ( $bugs && $revisions ) {
2 ignored issues
show
Bug Best Practice introduced by
The expression $bugs of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
Bug Best Practice introduced by
The expression $revisions of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
241
			throw new \RuntimeException('The "--bugs" and "--revisions" options are mutually exclusive.');
242
		}
243
244
		$missing_revisions = array();
245
		$revisions_by_path = $this->getRevisionsByPath();
246
247
		if ( $revisions ) {
1 ignored issue
show
Bug Best Practice introduced by
The expression $revisions of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
248
			$revisions = $this->_revisionListParser->expandRanges($revisions);
249
			$revisions_by_path = array_intersect($revisions_by_path, $revisions);
250
			$missing_revisions = array_diff($revisions, $revisions_by_path);
251
		}
252
		elseif ( $bugs ) {
1 ignored issue
show
Bug Best Practice introduced by
The expression $bugs of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
253
			// Only show bug-related revisions on given path. The $missing_revisions is always empty.
254
			$revisions_from_bugs = $this->_revisionLog->find('bugs', $bugs);
255
			$revisions_by_path = array_intersect($revisions_by_path, $revisions_from_bugs);
256
		}
257
258
		$merged_by = $this->getList($this->io->getOption('merged-by'));
259
260
		if ( $merged_by ) {
1 ignored issue
show
Bug Best Practice introduced by
The expression $merged_by of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
261
			$merged_by = $this->_revisionListParser->expandRanges($merged_by);
262
			$revisions_by_path = $this->_revisionLog->find('merges', $merged_by);
263
		}
264
265
		if ( $this->io->getOption('merges') ) {
266
			$revisions_by_path = array_intersect($revisions_by_path, $this->_revisionLog->find('merges', 'all_merges'));
267
		}
268
		elseif ( $this->io->getOption('no-merges') ) {
269
			$revisions_by_path = array_diff($revisions_by_path, $this->_revisionLog->find('merges', 'all_merges'));
270
		}
271
272
		if ( $this->io->getOption('merged') ) {
273
			$revisions_by_path = array_intersect($revisions_by_path, $this->_revisionLog->find('merges', 'all_merged'));
274
		}
275
		elseif ( $this->io->getOption('not-merged') ) {
276
			$revisions_by_path = array_diff($revisions_by_path, $this->_revisionLog->find('merges', 'all_merged'));
277
		}
278
279
		$action = $this->io->getOption('action');
280
281
		if ( $action ) {
282
			if ( !in_array($action, $this->getAllActions()) ) {
283
				throw new CommandException('The "' . $action . '" action is unknown.');
284
			}
285
286
			$revisions_by_path = array_intersect(
287
				$revisions_by_path,
288
				$this->_revisionLog->find('paths', 'action:' . $action)
289
			);
290
		}
291
292
		$kind = $this->io->getOption('kind');
293
294
		if ( $kind ) {
295
			if ( !in_array($kind, $this->getAllKinds()) ) {
296
				throw new CommandException('The "' . $kind . '" kind is unknown.');
297
			}
298
299
			$revisions_by_path = array_intersect(
300
				$revisions_by_path,
301
				$this->_revisionLog->find('paths', 'kind:' . $kind)
302
			);
303
		}
304
305
		if ( $missing_revisions ) {
1 ignored issue
show
Bug Best Practice introduced by
The expression $missing_revisions of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
306
			throw new CommandException($this->getMissingRevisionsErrorMessage($missing_revisions));
307
		}
308
		elseif ( !$revisions_by_path ) {
1 ignored issue
show
Bug Best Practice introduced by
The expression $revisions_by_path of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
309
			throw new CommandException('No matching revisions found.');
310
		}
311
312
		rsort($revisions_by_path, SORT_NUMERIC);
313
314
		if ( $bugs || $revisions ) {
2 ignored issues
show
Bug Best Practice introduced by
The expression $bugs of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
Bug Best Practice introduced by
The expression $revisions of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
315
			// Don't limit revisions, when provided explicitly by user.
316
			$revisions_by_path_with_limit = $revisions_by_path;
317
		}
318
		else {
319
			// Apply limit only, when no explicit bugs/revisions are set.
320
			$revisions_by_path_with_limit = array_slice($revisions_by_path, 0, $this->getMaxCount());
321
		}
322
323
		$revisions_by_path_count = count($revisions_by_path);
324
		$revisions_by_path_with_limit_count = count($revisions_by_path_with_limit);
325
326
		if ( $revisions_by_path_with_limit_count === $revisions_by_path_count ) {
327
			$this->io->writeln(sprintf(
328
				' * Showing <info>%d</info> revision(-s) in %s:',
329
				$revisions_by_path_with_limit_count,
330
				$this->getRevisionLogIdentifier()
331
			));
332
		}
333
		else {
334
			$this->io->writeln(sprintf(
335
				' * Showing <info>%d</info> of <info>%d</info> revision(-s) in %s:',
336
				$revisions_by_path_with_limit_count,
337
				$revisions_by_path_count,
338
				$this->getRevisionLogIdentifier()
339
			));
340
		}
341
342
		$searching_duration = microtime(true) - $searching_start;
343
344
		$printing_start = microtime(true);
345
		$this->printRevisions($revisions_by_path_with_limit);
346
		$printing_duration = microtime(true) - $printing_start;
347
348
		$debug_info = 'Generation Time: <info>' . round($searching_duration + $printing_duration, 2) . 's</info>';
349
		$debug_info .= ' (';
350
		$debug_info .= 'searching: <info>' . round($searching_duration, 2) . 's</info>;';
351
		$debug_info .= ' printing: <info>' . round($printing_duration, 2) . 's</info>';
352
		$debug_info .= ').';
353
354
		$this->io->writeln(
355
			$debug_info
356
		);
357
	}
358
359
	/**
360
	 * Returns all refs.
361
	 *
362
	 * @return array
363
	 */
364
	protected function getAllRefs()
365
	{
366
		$ret = parent::getAllRefs();
367
		$ret[] = self::ALL_REFS;
368
369
		return $ret;
370
	}
371
372
	/**
373
	 * Returns all actions.
374
	 *
375
	 * @return array
376
	 */
377
	protected function getAllActions()
378
	{
379
		return array('A', 'M', 'R', 'D');
380
	}
381
382
	/**
383
	 * Returns all actions.
384
	 *
385
	 * @return array
386
	 */
387
	protected function getAllKinds()
388
	{
389
		return array('dir', 'file');
390
	}
391
392
	/**
393
	 * Returns revision log identifier.
394
	 *
395
	 * @return string
396
	 */
397
	protected function getRevisionLogIdentifier()
398
	{
399
		$ret = '<info>' . $this->_revisionLog->getProjectPath() . '</info> project';
400
401
		$ref_name = $this->_revisionLog->getRefName();
402
403
		if ( $ref_name ) {
404
			$ret .= ' (ref: <info>' . $ref_name . '</info>)';
405
		}
406
		else {
407
			$ret .= ' (all refs)';
408
		}
409
410
		return $ret;
411
	}
412
413
	/**
414
	 * Shows error about missing revisions.
415
	 *
416
	 * @param array $missing_revisions Missing revisions.
417
	 *
418
	 * @return string
419
	 */
420
	protected function getMissingRevisionsErrorMessage(array $missing_revisions)
421
	{
422
		$refs = $this->io->getOption('refs');
423
		$missing_revisions = implode(', ', $missing_revisions);
424
425
		if ( $refs ) {
426
			$revision_source = 'in "' . $refs . '" ref(-s)';
427
		}
428
		else {
429
			$revision_source = 'at "' . $this->getWorkingCopyUrl() . '" url';
430
		}
431
432
		return 'The ' . $missing_revisions . ' revision(-s) not found ' . $revision_source . '.';
433
	}
434
435
	/**
436
	 * Returns list of revisions by path.
437
	 *
438
	 * @return array
439
	 * @throws CommandException When given path doesn't exist.
440
	 * @throws CommandException When given refs doesn't exist.
441
	 */
442
	protected function getRevisionsByPath()
443
	{
444
		// When "$path" points to deleted path the "$wc_path" will be parent folder of it (hopefully existing folder).
445
		$path = $this->io->getArgument('path');
446
		$wc_path = $this->getWorkingCopyPath();
447
448
		$refs = $this->getList($this->io->getOption('refs'));
449
		$relative_path = $this->repositoryConnector->getRelativePath($wc_path);
450
451
		if ( !$this->repositoryConnector->isUrl($wc_path) ) {
452
			$relative_path .= $this->_getPathDifference($wc_path, $path);
453
		}
454
455
		$relative_path = $this->_crossReferencePathFromRepository($relative_path);
456
457
		if ( $relative_path === null ) {
458
			throw new CommandException(
459
				'The "' . $path . '" path not found in "' . $this->_revisionLog->getProjectPath() . '" project.'
460
			);
461
		}
462
463
		if ( $refs ) {
1 ignored issue
show
Bug Best Practice introduced by
The expression $refs of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
464
			$incorrect_refs = array_diff($refs, $this->getAllRefs());
465
466
			if ( $incorrect_refs ) {
1 ignored issue
show
Bug Best Practice introduced by
The expression $incorrect_refs of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
467
				throw new CommandException(
468
					'The following refs are unknown: "' . implode('", "', $incorrect_refs) . '".'
469
				);
470
			}
471
472
			return $this->_revisionLog->find('refs', $refs);
473
		}
474
475
		return $this->_revisionLog->find('paths', $relative_path);
476
	}
477
478
	/**
479
	 * Returns difference between 2 paths.
480
	 *
481
	 * @param string $main_path Main path.
482
	 * @param string $sub_path  Sub path.
483
	 *
484
	 * @return string
485
	 */
486
	private function _getPathDifference($main_path, $sub_path)
487
	{
488
		if ( $sub_path === '.' || strpos($sub_path, '../') !== false ) {
489
			$sub_path = realpath($sub_path);
490
		}
491
492
		$adapted_sub_path = $sub_path;
493
494
		do {
495
			$sub_path_pos = strpos($main_path, $adapted_sub_path);
496
497
			if ( $sub_path_pos !== false ) {
498
				break;
499
			}
500
501
			$adapted_sub_path = dirname($adapted_sub_path);
502
		} while ( $adapted_sub_path !== '.' );
503
504
		// No sub-matches.
505
		if ( !strlen($adapted_sub_path) ) {
506
			return '';
507
		}
508
509
		return str_replace($adapted_sub_path, '', $sub_path);
510
	}
511
512
	/**
513
	 * Determines path kind from repository.
514
	 *
515
	 * @param string $path Path.
516
	 *
517
	 * @return string|null
518
	 */
519
	private function _crossReferencePathFromRepository($path)
520
	{
521
		$path = rtrim($path, '/');
522
		$try_paths = array($path, $path . '/');
523
524
		foreach ( $try_paths as $try_path ) {
525
			if ( $this->_revisionLog->find('paths', 'exact:' . $try_path) ) {
526
				return $try_path;
527
			}
528
		}
529
530
		return null;
531
	}
532
533
	/**
534
	 * Returns displayed revision limit.
535
	 *
536
	 * @return integer
537
	 */
538
	protected function getMaxCount()
539
	{
540
		$max_count = $this->io->getOption('max-count');
541
542
		if ( $max_count !== null ) {
543
			return $max_count;
544
		}
545
546
		return $this->getSetting(self::SETTING_LOG_LIMIT);
547
	}
548
549
	/**
550
	 * Prints revisions.
551
	 *
552
	 * @param array $revisions Revisions.
553
	 *
554
	 * @return void
555
	 */
556
	protected function printRevisions(array $revisions)
557
	{
558
		$column_mapping = array(
559
			'with-details' => RevisionPrinter::COLUMN_DETAILS,
560
			'with-summary' => RevisionPrinter::COLUMN_SUMMARY,
561
			'with-refs' => RevisionPrinter::COLUMN_REFS,
562
			'with-merge-oracle' => RevisionPrinter::COLUMN_MERGE_ORACLE,
563
			'with-merge-status' => RevisionPrinter::COLUMN_MERGE_STATUS,
564
		);
565
566
		foreach ( $column_mapping as $option_name => $column ) {
567
			if ( $this->io->getOption($option_name) ) {
568
				$this->_revisionPrinter->withColumn($column);
569
			}
570
		}
571
572
		$this->_revisionPrinter->setMergeConflictRegExps($this->getSetting(self::SETTING_LOG_MERGE_CONFLICT_REGEXPS));
573
		$this->_revisionPrinter->setLogMessageLimit($this->getSetting(self::SETTING_LOG_MESSAGE_LIMIT));
574
575
		$wc_path = $this->getWorkingCopyPath();
576
577
		if ( !$this->repositoryConnector->isUrl($wc_path) ) {
578
			$this->_revisionPrinter->setCurrentRevision(
579
				$this->repositoryConnector->getLastRevision($wc_path)
580
			);
581
		}
582
583
		$this->_revisionPrinter->printRevisions($this->_revisionLog, $revisions, $this->io->getOutput());
584
	}
585
586
	/**
587
	 * Returns list of config settings.
588
	 *
589
	 * @return AbstractConfigSetting[]
590
	 */
591
	public function getConfigSettings()
592
	{
593
		return array(
594
			new IntegerConfigSetting(self::SETTING_LOG_LIMIT, 10),
595
			new IntegerConfigSetting(self::SETTING_LOG_MESSAGE_LIMIT, 68),
596
			new RegExpsConfigSetting(self::SETTING_LOG_MERGE_CONFLICT_REGEXPS, '#/composer\.lock$#'),
597
		);
598
	}
599
600
	/**
601
	 * Returns option names, that makes sense to use in aggregation mode.
602
	 *
603
	 * @return array
604
	 */
605
	public function getAggregatedOptions()
606
	{
607
		return array(
608
			'merges', 'no-merges', 'merged', 'not-merged', 'action',
609
			'kind', 'with-details', 'with-summary', 'with-refs',
610
			'with-merge-oracle', 'with-merge-status', 'max-count',
611
		);
612
	}
613
614
}
615